@marimo-team/islands 0.24.1-dev115 → 0.24.1-dev116

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 (39) hide show
  1. package/dist/{ConnectedDataExplorerComponent-3vyrwCHu.js → ConnectedDataExplorerComponent-BabDOEkd.js} +10 -10
  2. package/dist/{ErrorBoundary-QF0xsxMw.js → ErrorBoundary-DXp6EXOC.js} +2 -2
  3. package/dist/{any-language-editor-B2e3EkTe.js → any-language-editor-CpTnK43-.js} +3 -3
  4. package/dist/{chat-ui-BgGHMO2G.js → chat-ui-B2KTPWqm.js} +15 -15
  5. package/dist/{check-C_-c2CXl.js → check-CHig47QV.js} +1 -1
  6. package/dist/{common-Cdx64lyR.js → common-mAFq987V.js} +7588 -7544
  7. package/dist/{copy-D4GHy7GA.js → copy-CD7S58CY.js} +1 -1
  8. package/dist/{dist-mymH-A_x.js → dist-3_o3T78I.js} +14 -14
  9. package/dist/{dropdown-menu-Div6gwlw.js → dropdown-menu-D1s8H8Ow.js} +123 -123
  10. package/dist/{error-banner-DmgOcFS3.js → error-banner-WDhUzJyg.js} +202 -202
  11. package/dist/{esm-CmFEQJjP.js → esm-CesmlDrs.js} +1 -1
  12. package/dist/{extends-CGTKDWHv.js → extends-BPB6_lTK.js} +3 -3
  13. package/dist/{formats-DuRRWVwb.js → formats-DrWM-ouO.js} +1 -1
  14. package/dist/{glide-data-editor-ekJ5GwaZ.js → glide-data-editor-B-3cUJQd.js} +7 -7
  15. package/dist/{glide-utils-Dwc8Eh8G.js → glide-utils-NShAPPtn.js} +2 -2
  16. package/dist/{html-to-image-u8Ik6EnK.js → html-to-image-DqqHcuV2.js} +3378 -3378
  17. package/dist/{label-DdGS_CZZ.js → label-lwzzBHUW.js} +1 -1
  18. package/dist/main.js +792 -792
  19. package/dist/{mermaid-Bt45Zzl4.js → mermaid-DWMOBSe8.js} +3 -3
  20. package/dist/{process-output-DQiqt-_U.js → process-output-D5dqSIGW.js} +3 -3
  21. package/dist/{reveal-component-tQ-rgxcQ.js → reveal-component-DU6Wrhzv.js} +8 -8
  22. package/dist/{schemas-BjeOpZLk.js → schemas-DzK6U94N.js} +1379 -1363
  23. package/dist/{select-DotAQ4jp.js → select-3qHpFKF9.js} +286 -286
  24. package/dist/{spec-BesaYkGC.js → spec-DzTo7SI8.js} +4 -4
  25. package/dist/style.css +1 -1
  26. package/dist/{toDate-CrAIOASL.js → toDate-Cq6SCTVJ.js} +2 -2
  27. package/dist/{tooltip-COXZxyl7.js → tooltip-Dt77sBeT.js} +87 -87
  28. package/dist/{useAsyncData-x0_tWDWI.js → useAsyncData-DqlulK9M.js} +1 -1
  29. package/dist/{useDateFormatter-B3V__WqX.js → useDateFormatter-Cp9Jdxls.js} +2 -2
  30. package/dist/{useDeepCompareMemoize-KaRHJEEU.js → useDeepCompareMemoize-Ceu-LMdC.js} +1 -1
  31. package/dist/{useLifecycle-x0OriHo-.js → useLifecycle-DmYfrWCI.js} +2 -2
  32. package/dist/{useTheme-Bm9_FyqO.js → useTheme-CWrCsZgw.js} +1 -1
  33. package/dist/{vega-component-nD2oP6WN.js → vega-component-Dzo_03Dh.js} +7 -7
  34. package/package.json +1 -1
  35. package/src/components/editor/Output.tsx +40 -0
  36. package/src/components/editor/__tests__/Output.test.tsx +85 -2
  37. package/src/components/ui/__tests__/fullscreen.test.tsx +88 -0
  38. package/src/components/ui/fullscreen.tsx +43 -1
  39. package/src/hooks/useEventListener.ts +1 -1
@@ -1,8 +1,8 @@
1
1
  import { t as e } from "./rolldown-runtime-Cb76FRpK.js";
2
2
  import { g as t } from "./button-CKBkqR9J.js";
3
3
  import { t as n } from "./compiler-runtime-CAH9RLw2.js";
4
- import { u as r } from "./dist-mymH-A_x.js";
5
- import { E as i, _ as a, a as o, b as s } from "./useTheme-Bm9_FyqO.js";
4
+ import { u as r } from "./dist-3_o3T78I.js";
5
+ import { E as i, _ as a, a as o, b as s } from "./useTheme-CWrCsZgw.js";
6
6
  import { t as c } from "./invariant-DLmrl-hA.js";
7
7
  var l = r("circle-question-mark", [
8
8
  ["circle", {
@@ -2,116 +2,116 @@ import { a as e } from "./rolldown-runtime-Cb76FRpK.js";
2
2
  import { d as t, h as n, p as r } from "./button-CKBkqR9J.js";
3
3
  import { t as i } from "./react-DMWcHin-.js";
4
4
  import { t as a } from "./compiler-runtime-CAH9RLw2.js";
5
- import { a as o, i as s, n as c, r as l, s as u, t as d } from "./dist-mymH-A_x.js";
5
+ import { a as o, i as s, n as c, r as l, s as u, t as d } from "./dist-3_o3T78I.js";
6
6
  import { t as f } from "./jsx-runtime-CpoKNRgu.js";
7
- import { Bc as p, Dc as m, Ec as h, Hc as ee, Kc as g, Lc as _, Pc as v, Vc as y, Wc as b, kc as x, qc as S } from "./schemas-BjeOpZLk.js";
7
+ import { Ac as p, Dc as m, Fc as h, Gc as g, Hc as _, Jc as v, Oc as y, Rc as b, Uc as ee, Vc as te, qc as x } from "./schemas-DzK6U94N.js";
8
8
  //#region ../node_modules/.pnpm/@radix-ui+react-tooltip@1.2.8_@types+react-dom@19.2.3_@types+react@19.2.10__@types+reac_6c936392a1aa34d496e116dc55299197/node_modules/@radix-ui/react-tooltip/dist/index.mjs
9
- var C = /* @__PURE__ */ e(i(), 1), w = f(), [T, E] = g("Tooltip", [o]), D = o(), O = "TooltipProvider", te = 700, k = "tooltip.open", [ne, A] = T(O), j = (e) => {
10
- let { __scopeTooltip: t, delayDuration: n = te, skipDelayDuration: r = 300, disableHoverableContent: i = !1, children: a } = e, o = C.useRef(!0), s = C.useRef(!1), c = C.useRef(0);
11
- return C.useEffect(() => {
9
+ var S = /* @__PURE__ */ e(i(), 1), C = f(), [w, T] = x("Tooltip", [o]), E = o(), D = "TooltipProvider", ne = 700, O = "tooltip.open", [re, k] = w(D), A = (e) => {
10
+ let { __scopeTooltip: t, delayDuration: n = ne, skipDelayDuration: r = 300, disableHoverableContent: i = !1, children: a } = e, o = S.useRef(!0), s = S.useRef(!1), c = S.useRef(0);
11
+ return S.useEffect(() => {
12
12
  let e = c.current;
13
13
  return () => window.clearTimeout(e);
14
- }, []), /* @__PURE__ */ (0, w.jsx)(ne, {
14
+ }, []), /* @__PURE__ */ (0, C.jsx)(re, {
15
15
  scope: t,
16
16
  isOpenDelayedRef: o,
17
17
  delayDuration: n,
18
- onOpen: C.useCallback(() => {
18
+ onOpen: S.useCallback(() => {
19
19
  window.clearTimeout(c.current), o.current = !1;
20
20
  }, []),
21
- onClose: C.useCallback(() => {
21
+ onClose: S.useCallback(() => {
22
22
  window.clearTimeout(c.current), c.current = window.setTimeout(() => o.current = !0, r);
23
23
  }, [r]),
24
24
  isPointerInTransitRef: s,
25
- onPointerInTransitChange: C.useCallback((e) => {
25
+ onPointerInTransitChange: S.useCallback((e) => {
26
26
  s.current = e;
27
27
  }, []),
28
28
  disableHoverableContent: i,
29
29
  children: a
30
30
  });
31
31
  };
32
- j.displayName = O;
33
- var M = "Tooltip", [N, P] = T(M), F = (e) => {
34
- let { __scopeTooltip: t, children: n, open: r, defaultOpen: i, onOpenChange: a, disableHoverableContent: o, delayDuration: c } = e, l = A(M, e.__scopeTooltip), u = D(t), [d, f] = C.useState(null), m = p(), h = C.useRef(0), g = o ?? l.disableHoverableContent, _ = c ?? l.delayDuration, v = C.useRef(!1), [y, b] = ee({
32
+ A.displayName = D;
33
+ var j = "Tooltip", [M, N] = w(j), P = (e) => {
34
+ let { __scopeTooltip: t, children: n, open: r, defaultOpen: i, onOpenChange: a, disableHoverableContent: o, delayDuration: c } = e, l = k(j, e.__scopeTooltip), u = E(t), [d, f] = S.useState(null), p = te(), m = S.useRef(0), h = o ?? l.disableHoverableContent, g = c ?? l.delayDuration, _ = S.useRef(!1), [v, y] = ee({
35
35
  prop: r,
36
36
  defaultProp: i ?? !1,
37
37
  onChange: (e) => {
38
- e ? (l.onOpen(), document.dispatchEvent(new CustomEvent(k))) : l.onClose(), a?.(e);
38
+ e ? (l.onOpen(), document.dispatchEvent(new CustomEvent(O))) : l.onClose(), a?.(e);
39
39
  },
40
- caller: M
41
- }), x = C.useMemo(() => y ? v.current ? "delayed-open" : "instant-open" : "closed", [y]), S = C.useCallback(() => {
42
- window.clearTimeout(h.current), h.current = 0, v.current = !1, b(!0);
43
- }, [b]), T = C.useCallback(() => {
44
- window.clearTimeout(h.current), h.current = 0, b(!1);
45
- }, [b]), E = C.useCallback(() => {
46
- window.clearTimeout(h.current), h.current = window.setTimeout(() => {
47
- v.current = !0, b(!0), h.current = 0;
48
- }, _);
49
- }, [_, b]);
50
- return C.useEffect(() => () => {
51
- h.current &&= (window.clearTimeout(h.current), 0);
52
- }, []), /* @__PURE__ */ (0, w.jsx)(s, {
40
+ caller: j
41
+ }), b = S.useMemo(() => v ? _.current ? "delayed-open" : "instant-open" : "closed", [v]), x = S.useCallback(() => {
42
+ window.clearTimeout(m.current), m.current = 0, _.current = !1, y(!0);
43
+ }, [y]), w = S.useCallback(() => {
44
+ window.clearTimeout(m.current), m.current = 0, y(!1);
45
+ }, [y]), T = S.useCallback(() => {
46
+ window.clearTimeout(m.current), m.current = window.setTimeout(() => {
47
+ _.current = !0, y(!0), m.current = 0;
48
+ }, g);
49
+ }, [g, y]);
50
+ return S.useEffect(() => () => {
51
+ m.current &&= (window.clearTimeout(m.current), 0);
52
+ }, []), /* @__PURE__ */ (0, C.jsx)(s, {
53
53
  ...u,
54
- children: /* @__PURE__ */ (0, w.jsx)(N, {
54
+ children: /* @__PURE__ */ (0, C.jsx)(M, {
55
55
  scope: t,
56
- contentId: m,
57
- open: y,
58
- stateAttribute: x,
56
+ contentId: p,
57
+ open: v,
58
+ stateAttribute: b,
59
59
  trigger: d,
60
60
  onTriggerChange: f,
61
- onTriggerEnter: C.useCallback(() => {
62
- l.isOpenDelayedRef.current ? E() : S();
61
+ onTriggerEnter: S.useCallback(() => {
62
+ l.isOpenDelayedRef.current ? T() : x();
63
63
  }, [
64
64
  l.isOpenDelayedRef,
65
- E,
66
- S
65
+ T,
66
+ x
67
67
  ]),
68
- onTriggerLeave: C.useCallback(() => {
69
- g ? T() : (window.clearTimeout(h.current), h.current = 0);
70
- }, [T, g]),
71
- onOpen: S,
72
- onClose: T,
73
- disableHoverableContent: g,
68
+ onTriggerLeave: S.useCallback(() => {
69
+ h ? w() : (window.clearTimeout(m.current), m.current = 0);
70
+ }, [w, h]),
71
+ onOpen: x,
72
+ onClose: w,
73
+ disableHoverableContent: h,
74
74
  children: n
75
75
  })
76
76
  });
77
77
  };
78
- F.displayName = M;
79
- var I = "TooltipTrigger", L = C.forwardRef((e, t) => {
80
- let { __scopeTooltip: n, ...i } = e, a = P(I, n), o = A(I, n), s = D(n), c = C.useRef(null), l = r(t, c, a.onTriggerChange), u = C.useRef(!1), f = C.useRef(!1), p = C.useCallback(() => u.current = !1, []);
81
- return C.useEffect(() => () => document.removeEventListener("pointerup", p), [p]), /* @__PURE__ */ (0, w.jsx)(d, {
78
+ P.displayName = j;
79
+ var F = "TooltipTrigger", I = S.forwardRef((e, t) => {
80
+ let { __scopeTooltip: n, ...i } = e, a = N(F, n), o = k(F, n), s = E(n), c = S.useRef(null), l = r(t, c, a.onTriggerChange), u = S.useRef(!1), f = S.useRef(!1), p = S.useCallback(() => u.current = !1, []);
81
+ return S.useEffect(() => () => document.removeEventListener("pointerup", p), [p]), /* @__PURE__ */ (0, C.jsx)(d, {
82
82
  asChild: !0,
83
83
  ...s,
84
- children: /* @__PURE__ */ (0, w.jsx)(S.button, {
84
+ children: /* @__PURE__ */ (0, C.jsx)(v.button, {
85
85
  "aria-describedby": a.open ? a.contentId : void 0,
86
86
  "data-state": a.stateAttribute,
87
87
  ...i,
88
88
  ref: l,
89
- onPointerMove: b(e.onPointerMove, (e) => {
89
+ onPointerMove: g(e.onPointerMove, (e) => {
90
90
  e.pointerType !== "touch" && !f.current && !o.isPointerInTransitRef.current && (a.onTriggerEnter(), f.current = !0);
91
91
  }),
92
- onPointerLeave: b(e.onPointerLeave, () => {
92
+ onPointerLeave: g(e.onPointerLeave, () => {
93
93
  a.onTriggerLeave(), f.current = !1;
94
94
  }),
95
- onPointerDown: b(e.onPointerDown, () => {
95
+ onPointerDown: g(e.onPointerDown, () => {
96
96
  a.open && a.onClose(), u.current = !0, document.addEventListener("pointerup", p, { once: !0 });
97
97
  }),
98
- onFocus: b(e.onFocus, () => {
98
+ onFocus: g(e.onFocus, () => {
99
99
  u.current || a.onOpen();
100
100
  }),
101
- onBlur: b(e.onBlur, a.onClose),
102
- onClick: b(e.onClick, a.onClose)
101
+ onBlur: g(e.onBlur, a.onClose),
102
+ onClick: g(e.onClick, a.onClose)
103
103
  })
104
104
  });
105
105
  });
106
- L.displayName = I;
107
- var R = "TooltipPortal", [re, z] = T(R, { forceMount: void 0 }), B = (e) => {
108
- let { __scopeTooltip: t, forceMount: n, children: r, container: i } = e, a = P(R, t);
109
- return /* @__PURE__ */ (0, w.jsx)(re, {
106
+ I.displayName = F;
107
+ var L = "TooltipPortal", [R, z] = w(L, { forceMount: void 0 }), B = (e) => {
108
+ let { __scopeTooltip: t, forceMount: n, children: r, container: i } = e, a = N(L, t);
109
+ return /* @__PURE__ */ (0, C.jsx)(R, {
110
110
  scope: t,
111
111
  forceMount: n,
112
- children: /* @__PURE__ */ (0, w.jsx)(y, {
112
+ children: /* @__PURE__ */ (0, C.jsx)(_, {
113
113
  present: n || a.open,
114
- children: /* @__PURE__ */ (0, w.jsx)(v, {
114
+ children: /* @__PURE__ */ (0, C.jsx)(h, {
115
115
  asChild: !0,
116
116
  container: i,
117
117
  children: r
@@ -119,32 +119,32 @@ var R = "TooltipPortal", [re, z] = T(R, { forceMount: void 0 }), B = (e) => {
119
119
  })
120
120
  });
121
121
  };
122
- B.displayName = R;
123
- var V = "TooltipContent", H = C.forwardRef((e, t) => {
124
- let n = z(V, e.__scopeTooltip), { forceMount: r = n.forceMount, side: i = "top", ...a } = e, o = P(V, e.__scopeTooltip);
125
- return /* @__PURE__ */ (0, w.jsx)(y, {
122
+ B.displayName = L;
123
+ var V = "TooltipContent", H = S.forwardRef((e, t) => {
124
+ let n = z(V, e.__scopeTooltip), { forceMount: r = n.forceMount, side: i = "top", ...a } = e, o = N(V, e.__scopeTooltip);
125
+ return /* @__PURE__ */ (0, C.jsx)(_, {
126
126
  present: r || o.open,
127
- children: o.disableHoverableContent ? /* @__PURE__ */ (0, w.jsx)(G, {
127
+ children: o.disableHoverableContent ? /* @__PURE__ */ (0, C.jsx)(G, {
128
128
  side: i,
129
129
  ...a,
130
130
  ref: t
131
- }) : /* @__PURE__ */ (0, w.jsx)(ie, {
131
+ }) : /* @__PURE__ */ (0, C.jsx)(ie, {
132
132
  side: i,
133
133
  ...a,
134
134
  ref: t
135
135
  })
136
136
  });
137
- }), ie = C.forwardRef((e, t) => {
138
- let n = P(V, e.__scopeTooltip), i = A(V, e.__scopeTooltip), a = C.useRef(null), o = r(t, a), [s, c] = C.useState(null), { trigger: l, onClose: u } = n, d = a.current, { onPointerInTransitChange: f } = i, p = C.useCallback(() => {
137
+ }), ie = S.forwardRef((e, t) => {
138
+ let n = N(V, e.__scopeTooltip), i = k(V, e.__scopeTooltip), a = S.useRef(null), o = r(t, a), [s, c] = S.useState(null), { trigger: l, onClose: u } = n, d = a.current, { onPointerInTransitChange: f } = i, p = S.useCallback(() => {
139
139
  c(null), f(!1);
140
- }, [f]), m = C.useCallback((e, t) => {
140
+ }, [f]), m = S.useCallback((e, t) => {
141
141
  let n = e.currentTarget, r = {
142
142
  x: e.clientX,
143
143
  y: e.clientY
144
144
  }, i = se(r, oe(r, n.getBoundingClientRect())), a = ce(t.getBoundingClientRect()), o = ue([...i, ...a]);
145
145
  c(o), f(!0);
146
146
  }, [f]);
147
- return C.useEffect(() => () => p(), [p]), C.useEffect(() => {
147
+ return S.useEffect(() => () => p(), [p]), S.useEffect(() => {
148
148
  if (l && d) {
149
149
  let e = (e) => m(e, d), t = (e) => m(e, l);
150
150
  return l.addEventListener("pointerleave", e), d.addEventListener("pointerleave", t), () => {
@@ -156,7 +156,7 @@ var V = "TooltipContent", H = C.forwardRef((e, t) => {
156
156
  d,
157
157
  m,
158
158
  p
159
- ]), C.useEffect(() => {
159
+ ]), S.useEffect(() => {
160
160
  if (s) {
161
161
  let e = (e) => {
162
162
  let t = e.target, n = {
@@ -173,27 +173,27 @@ var V = "TooltipContent", H = C.forwardRef((e, t) => {
173
173
  s,
174
174
  u,
175
175
  p
176
- ]), /* @__PURE__ */ (0, w.jsx)(G, {
176
+ ]), /* @__PURE__ */ (0, C.jsx)(G, {
177
177
  ...e,
178
178
  ref: o
179
179
  });
180
- }), [ae, U] = T(M, { isInside: !1 }), W = t("TooltipContent"), G = C.forwardRef((e, t) => {
181
- let { __scopeTooltip: n, children: r, "aria-label": i, onEscapeKeyDown: a, onPointerDownOutside: o, ...s } = e, c = P(V, n), d = D(n), { onClose: f } = c;
182
- return C.useEffect(() => (document.addEventListener(k, f), () => document.removeEventListener(k, f)), [f]), C.useEffect(() => {
180
+ }), [ae, U] = w(j, { isInside: !1 }), W = t("TooltipContent"), G = S.forwardRef((e, t) => {
181
+ let { __scopeTooltip: n, children: r, "aria-label": i, onEscapeKeyDown: a, onPointerDownOutside: o, ...s } = e, c = N(V, n), d = E(n), { onClose: f } = c;
182
+ return S.useEffect(() => (document.addEventListener(O, f), () => document.removeEventListener(O, f)), [f]), S.useEffect(() => {
183
183
  if (c.trigger) {
184
184
  let e = (e) => {
185
185
  e.target?.contains(c.trigger) && f();
186
186
  };
187
187
  return window.addEventListener("scroll", e, { capture: !0 }), () => window.removeEventListener("scroll", e, { capture: !0 });
188
188
  }
189
- }, [c.trigger, f]), /* @__PURE__ */ (0, w.jsx)(_, {
189
+ }, [c.trigger, f]), /* @__PURE__ */ (0, C.jsx)(b, {
190
190
  asChild: !0,
191
191
  disableOutsidePointerEvents: !1,
192
192
  onEscapeKeyDown: a,
193
193
  onPointerDownOutside: o,
194
194
  onFocusOutside: (e) => e.preventDefault(),
195
195
  onDismiss: f,
196
- children: /* @__PURE__ */ (0, w.jsxs)(l, {
196
+ children: /* @__PURE__ */ (0, C.jsxs)(l, {
197
197
  "data-state": c.stateAttribute,
198
198
  ...d,
199
199
  ...s,
@@ -206,10 +206,10 @@ var V = "TooltipContent", H = C.forwardRef((e, t) => {
206
206
  "--radix-tooltip-trigger-width": "var(--radix-popper-anchor-width)",
207
207
  "--radix-tooltip-trigger-height": "var(--radix-popper-anchor-height)"
208
208
  },
209
- children: [/* @__PURE__ */ (0, w.jsx)(W, { children: r }), /* @__PURE__ */ (0, w.jsx)(ae, {
209
+ children: [/* @__PURE__ */ (0, C.jsx)(W, { children: r }), /* @__PURE__ */ (0, C.jsx)(ae, {
210
210
  scope: n,
211
211
  isInside: !0,
212
- children: /* @__PURE__ */ (0, w.jsx)(u, {
212
+ children: /* @__PURE__ */ (0, C.jsx)(u, {
213
213
  id: c.contentId,
214
214
  role: "tooltip",
215
215
  children: i || r
@@ -219,9 +219,9 @@ var V = "TooltipContent", H = C.forwardRef((e, t) => {
219
219
  });
220
220
  });
221
221
  H.displayName = V;
222
- var K = "TooltipArrow", q = C.forwardRef((e, t) => {
223
- let { __scopeTooltip: n, ...r } = e, i = D(n);
224
- return U(K, n).isInside ? null : /* @__PURE__ */ (0, w.jsx)(c, {
222
+ var K = "TooltipArrow", q = S.forwardRef((e, t) => {
223
+ let { __scopeTooltip: n, ...r } = e, i = E(n);
224
+ return U(K, n).isInside ? null : /* @__PURE__ */ (0, C.jsx)(c, {
225
225
  ...i,
226
226
  ...r,
227
227
  ref: t
@@ -336,21 +336,21 @@ function de(e) {
336
336
  }
337
337
  return n.pop(), t.length === 1 && n.length === 1 && t[0].x === n[0].x && t[0].y === n[0].y ? t : t.concat(n);
338
338
  }
339
- var fe = j, pe = F, me = L, he = B, J = H, Y = a(), ge = (e) => {
339
+ var fe = A, pe = P, me = I, he = B, J = H, Y = a(), ge = (e) => {
340
340
  let t = (0, Y.c)(6), n, r;
341
341
  t[0] === e ? (n = t[1], r = t[2]) : ({delayDuration: r, ...n} = e, t[0] = e, t[1] = n, t[2] = r);
342
342
  let i = r === void 0 ? 400 : r, a;
343
- return t[3] !== i || t[4] !== n ? (a = /* @__PURE__ */ (0, w.jsx)(fe, {
343
+ return t[3] !== i || t[4] !== n ? (a = /* @__PURE__ */ (0, C.jsx)(fe, {
344
344
  delayDuration: i,
345
345
  ...n
346
346
  }), t[3] = i, t[4] = n, t[5] = a) : a = t[5], a;
347
- }, X = h(he), Z = pe, _e = m(J), Q = me, $ = C.forwardRef((e, t) => {
347
+ }, X = m(he), Z = pe, _e = y(J), Q = me, $ = S.forwardRef((e, t) => {
348
348
  let r = (0, Y.c)(11), i, a, o;
349
349
  r[0] === e ? (i = r[1], a = r[2], o = r[3]) : ({className: i, sideOffset: o, ...a} = e, r[0] = e, r[1] = i, r[2] = a, r[3] = o);
350
350
  let s = o === void 0 ? 4 : o, c;
351
351
  r[4] === i ? c = r[5] : (c = n("z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-xs data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1", i), r[4] = i, r[5] = c);
352
352
  let l;
353
- return r[6] !== a || r[7] !== t || r[8] !== s || r[9] !== c ? (l = /* @__PURE__ */ (0, w.jsx)(x, { children: /* @__PURE__ */ (0, w.jsx)(_e, {
353
+ return r[6] !== a || r[7] !== t || r[8] !== s || r[9] !== c ? (l = /* @__PURE__ */ (0, C.jsx)(p, { children: /* @__PURE__ */ (0, C.jsx)(_e, {
354
354
  ref: t,
355
355
  sideOffset: s,
356
356
  className: c,
@@ -364,23 +364,23 @@ var ve = (e) => {
364
364
  let u = s === void 0 || s, d = c === void 0 || c;
365
365
  if (i == null || i === "") return r;
366
366
  let f;
367
- t[9] !== d || t[10] !== r || t[11] !== l ? (f = /* @__PURE__ */ (0, w.jsx)(Q, {
367
+ t[9] !== d || t[10] !== r || t[11] !== l ? (f = /* @__PURE__ */ (0, C.jsx)(Q, {
368
368
  asChild: d,
369
369
  tabIndex: l,
370
370
  children: r
371
371
  }), t[9] = d, t[10] = r, t[11] = l, t[12] = f) : f = t[12];
372
372
  let p;
373
- t[13] !== n || t[14] !== i || t[15] !== o || t[16] !== u ? (p = u ? /* @__PURE__ */ (0, w.jsx)(X, { children: /* @__PURE__ */ (0, w.jsx)($, {
373
+ t[13] !== n || t[14] !== i || t[15] !== o || t[16] !== u ? (p = u ? /* @__PURE__ */ (0, C.jsx)(X, { children: /* @__PURE__ */ (0, C.jsx)($, {
374
374
  side: o,
375
375
  align: n,
376
376
  children: i
377
- }) }) : /* @__PURE__ */ (0, w.jsx)($, {
377
+ }) }) : /* @__PURE__ */ (0, C.jsx)($, {
378
378
  side: o,
379
379
  align: n,
380
380
  children: i
381
381
  }), t[13] = n, t[14] = i, t[15] = o, t[16] = u, t[17] = p) : p = t[17];
382
382
  let m;
383
- return t[18] !== a || t[19] !== f || t[20] !== p ? (m = /* @__PURE__ */ (0, w.jsxs)(Z, {
383
+ return t[18] !== a || t[19] !== f || t[20] !== p ? (m = /* @__PURE__ */ (0, C.jsxs)(Z, {
384
384
  disableHoverableContent: !0,
385
385
  ...a,
386
386
  children: [f, p]
@@ -1,7 +1,7 @@
1
1
  import { a as e } from "./rolldown-runtime-Cb76FRpK.js";
2
2
  import { t } from "./react-DMWcHin-.js";
3
3
  import { t as n } from "./compiler-runtime-CAH9RLw2.js";
4
- import { j as r } from "./useTheme-Bm9_FyqO.js";
4
+ import { j as r } from "./useTheme-CWrCsZgw.js";
5
5
  import { t as i } from "./invariant-DLmrl-hA.js";
6
6
  //#region src/hooks/useAsyncData.ts
7
7
  var a = n(), o = /* @__PURE__ */ e(t(), 1), s = {
@@ -1,7 +1,7 @@
1
1
  import { a as e } from "./rolldown-runtime-Cb76FRpK.js";
2
2
  import { t } from "./react-DMWcHin-.js";
3
- import { u as n } from "./dist-mymH-A_x.js";
4
- import { E as r } from "./select-DotAQ4jp.js";
3
+ import { u as n } from "./dist-3_o3T78I.js";
4
+ import { E as r } from "./select-3qHpFKF9.js";
5
5
  var i = n("chart-pie", [["path", {
6
6
  d: "M21 12c.552 0 1.005-.449.95-.998a10 10 0 0 0-8.953-8.951c-.55-.055-.998.398-.998.95v8a1 1 0 0 0 1 1z",
7
7
  key: "pzmjnu"
@@ -1,6 +1,6 @@
1
1
  import { a as e } from "./rolldown-runtime-Cb76FRpK.js";
2
2
  import { t } from "./react-DMWcHin-.js";
3
- import { A as n } from "./useTheme-Bm9_FyqO.js";
3
+ import { A as n } from "./useTheme-CWrCsZgw.js";
4
4
  //#region src/hooks/useDeepCompareMemoize.ts
5
5
  var r = /* @__PURE__ */ e(t(), 1);
6
6
  function i(e) {
@@ -2,9 +2,9 @@ import { a as e } from "./rolldown-runtime-Cb76FRpK.js";
2
2
  import { g as t, h as n, r } from "./button-CKBkqR9J.js";
3
3
  import { t as i } from "./react-DMWcHin-.js";
4
4
  import { t as a } from "./compiler-runtime-CAH9RLw2.js";
5
- import { u as o } from "./dist-mymH-A_x.js";
5
+ import { u as o } from "./dist-3_o3T78I.js";
6
6
  import { t as s } from "./jsx-runtime-CpoKNRgu.js";
7
- import { E as c, w as l } from "./useTheme-Bm9_FyqO.js";
7
+ import { E as c, w as l } from "./useTheme-CWrCsZgw.js";
8
8
  var u = o("calendar", [
9
9
  ["path", {
10
10
  d: "M8 2v4",
@@ -2,7 +2,7 @@ import { a as e } from "./rolldown-runtime-Cb76FRpK.js";
2
2
  import { a as t, g as n, s as r } from "./button-CKBkqR9J.js";
3
3
  import { t as i } from "./react-DMWcHin-.js";
4
4
  import { t as a } from "./compiler-runtime-CAH9RLw2.js";
5
- import { Cn as o, In as s, Jn as c, Sn as l, Tt as u, jn as d, kt as f, un as p, vt as m } from "./schemas-BjeOpZLk.js";
5
+ import { Cn as o, In as s, Jn as c, Sn as l, Tt as u, jn as d, kt as f, un as p, vt as m } from "./schemas-DzK6U94N.js";
6
6
  import { n as h, t as g } from "./_baseMerge-Dv8bBloN.js";
7
7
  //#region ../node_modules/.pnpm/lodash-es@4.18.1/node_modules/lodash-es/mergeWith.js
8
8
  var _ = h(function(e, t, n, r) {
@@ -2,20 +2,20 @@ import { a as e } from "./rolldown-runtime-Cb76FRpK.js";
2
2
  import { g as t, h as n, m as r, o as i } from "./button-CKBkqR9J.js";
3
3
  import { t as a } from "./react-DMWcHin-.js";
4
4
  import { t as o } from "./compiler-runtime-CAH9RLw2.js";
5
- import { c as s, v as c } from "./toDate-CrAIOASL.js";
5
+ import { c as s, v as c } from "./toDate-Cq6SCTVJ.js";
6
6
  import { t as l } from "./jsx-runtime-CpoKNRgu.js";
7
- import { n as u } from "./error-banner-DmgOcFS3.js";
8
- import { t as d } from "./tooltip-COXZxyl7.js";
7
+ import { n as u } from "./error-banner-WDhUzJyg.js";
8
+ import { t as d } from "./tooltip-Dt77sBeT.js";
9
9
  import { t as f } from "./debounce-C3jyATpc.js";
10
- import { j as p, n as ee } from "./useTheme-Bm9_FyqO.js";
10
+ import { j as p, n as ee } from "./useTheme-CWrCsZgw.js";
11
11
  import { c as m } from "./arrays-CN1djC4k.js";
12
12
  import { t as te } from "./objects-CzUgoMIF.js";
13
- import { t as h } from "./useAsyncData-x0_tWDWI.js";
14
- import { a as ne, i as re, n as ie, t as g } from "./formats-DuRRWVwb.js";
13
+ import { t as h } from "./useAsyncData-DqlulK9M.js";
14
+ import { a as ne, i as re, n as ie, t as g } from "./formats-DrWM-ouO.js";
15
15
  import { A as ae, n as oe } from "./vega-loader.browser-DEggZzni.js";
16
16
  import { t as se } from "./react-vega-DSD5aT7_.js";
17
17
  import { a as ce, n as _ } from "./loader-VZ__bv4g.js";
18
- import { t as le } from "./useDeepCompareMemoize-KaRHJEEU.js";
18
+ import { t as le } from "./useDeepCompareMemoize-Ceu-LMdC.js";
19
19
  import { t as ue } from "./semaphore-89jsoHtS.js";
20
20
  import { t as de } from "./use-vega-container-remeasure-DUW4tRxq.js";
21
21
  //#region src/plugins/impl/vega/fix-relative-url.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/islands",
3
- "version": "0.24.1-dev115",
3
+ "version": "0.24.1-dev116",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -18,10 +18,12 @@ import {
18
18
  ChevronsDownUpIcon,
19
19
  ChevronsUpDownIcon,
20
20
  ExpandIcon,
21
+ ShrinkIcon,
21
22
  } from "lucide-react";
22
23
  import { tooltipHandler } from "@/components/charts/tooltip";
23
24
  import { useExpandedOutput } from "@/core/cells/outputs";
24
25
  import { viewStateAtom } from "@/core/mode";
26
+ import { useEventListener } from "@/hooks/useEventListener";
25
27
  import { useIframeCapabilities } from "@/hooks/useIframeCapabilities";
26
28
  import { useOverflowDetection } from "@/hooks/useOverflowDetection";
27
29
  import { renderHTML } from "@/plugins/core/RenderHTML";
@@ -31,11 +33,13 @@ import { getContainerWidth } from "@/plugins/impl/vega/utils";
31
33
  import { useTheme } from "@/theme/useTheme";
32
34
  import { Events } from "@/utils/events";
33
35
  import { invariant } from "@/utils/invariant";
36
+ import { Logger } from "@/utils/Logger";
34
37
  import { processMimeBundle } from "@/utils/mime-types";
35
38
  import { Objects } from "@/utils/objects";
36
39
  import { LazyVegaEmbed } from "../charts/lazy";
37
40
  import { ChartLoadingState } from "../data-table/charts/components/chart-states";
38
41
  import { Button } from "../ui/button";
42
+ import { useIsFullScreen } from "../ui/fullscreen";
39
43
  import { Tabs, TabsContent, TabsList, TabsTrigger } from "../ui/tabs";
40
44
  import { Tooltip } from "../ui/tooltip";
41
45
  import { CsvViewer } from "./file-tree/renderers";
@@ -408,6 +412,12 @@ const Div = React.forwardRef<
408
412
  >((props, ref) => <div ref={ref} {...props} />);
409
413
  Div.displayName = "Div";
410
414
 
415
+ function exitFullscreen() {
416
+ document.exitFullscreen().catch((error) => {
417
+ Logger.warn("Failed to exit fullscreen", error);
418
+ });
419
+ }
420
+
411
421
  /**
412
422
  * Detects if there is overflow in the output area and adds a button to optionally expand
413
423
  */
@@ -425,6 +435,16 @@ const ExpandableOutput = React.memo(
425
435
  const [isExpanded, setIsExpanded] = useExpandedOutput(cellId);
426
436
  const isOverflowing = useOverflowDetection(containerRef);
427
437
  const { hasFullscreen } = useIframeCapabilities();
438
+ const isFullscreen = useIsFullScreen(containerRef);
439
+
440
+ // Not every host exits fullscreen on Escape by itself. A null target keeps
441
+ // the listener off every output that is not fullscreen.
442
+ useEventListener(isFullscreen ? document : null, "keydown", (event) => {
443
+ if (event.key !== "Escape" || !document.fullscreenElement) {
444
+ return;
445
+ }
446
+ exitFullscreen();
447
+ });
428
448
 
429
449
  return (
430
450
  <>
@@ -488,6 +508,26 @@ const ExpandableOutput = React.memo(
488
508
  isExpanded || forceExpand ? { maxHeight: "none" } : undefined
489
509
  }
490
510
  >
511
+ {/* Fullscreen paints this element only, and the action buttons sit
512
+ outside it. A host does not always draw an exit overlay, so the
513
+ output carries its own exit control. */}
514
+ {isFullscreen && (
515
+ <Tooltip content="Exit fullscreen" side="left">
516
+ <Button
517
+ data-testid="exit-fullscreen-output-button"
518
+ aria-label="Exit fullscreen"
519
+ className="absolute right-2 top-2 z-2 p-1 bg-background/90 border border-border hover:bg-muted print:hidden"
520
+ onClick={exitFullscreen}
521
+ size="xs"
522
+ variant="text"
523
+ >
524
+ <ShrinkIcon
525
+ className="size-4 opacity-60 hover:opacity-80"
526
+ strokeWidth={1.25}
527
+ />
528
+ </Button>
529
+ </Tooltip>
530
+ )}
491
531
  {children}
492
532
  </div>
493
533
  </div>
@@ -1,6 +1,6 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
- import { render, screen } from "@testing-library/react";
3
- import { describe, expect, it } from "vitest";
2
+ import { act, fireEvent, render, screen } from "@testing-library/react";
3
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
4
4
  import { cellId } from "@/__tests__/branded";
5
5
  import { TooltipProvider } from "@/components/ui/tooltip";
6
6
  import { OutputArea, OutputRenderer } from "../Output";
@@ -158,3 +158,86 @@ describe("OutputRenderer image and SVG rendering", () => {
158
158
  expect(imgElement).toHaveAttribute("src", base64PngDataUrl);
159
159
  });
160
160
  });
161
+
162
+ describe("OutputArea fullscreen exit control", () => {
163
+ let fullscreenElement: Element | null = null;
164
+ const exitFullscreen = vi.fn(() => Promise.resolve());
165
+
166
+ beforeEach(() => {
167
+ fullscreenElement = null;
168
+ exitFullscreen.mockClear();
169
+ Object.defineProperty(document, "fullscreenElement", {
170
+ configurable: true,
171
+ get: () => fullscreenElement,
172
+ });
173
+ Object.defineProperty(document, "exitFullscreen", {
174
+ configurable: true,
175
+ value: exitFullscreen,
176
+ });
177
+ });
178
+
179
+ // Drop the stubs so that the real document properties come back.
180
+ afterEach(() => {
181
+ Reflect.deleteProperty(document, "fullscreenElement");
182
+ Reflect.deleteProperty(document, "exitFullscreen");
183
+ });
184
+
185
+ const renderOutput = () =>
186
+ render(
187
+ <TooltipProvider>
188
+ <OutputArea
189
+ output={{
190
+ channel: "output",
191
+ data: "Hello World",
192
+ mimetype: "text/plain",
193
+ }}
194
+ cellId={cellId("test")}
195
+ stale={false}
196
+ loading={false}
197
+ allowExpand={true}
198
+ />
199
+ </TooltipProvider>,
200
+ );
201
+
202
+ const enterFullscreen = (container: HTMLElement) => {
203
+ fullscreenElement = container.querySelector('[data-cell-role="output"]');
204
+ act(() => {
205
+ document.dispatchEvent(new Event("fullscreenchange"));
206
+ });
207
+ };
208
+
209
+ it("hides the exit button outside fullscreen", () => {
210
+ renderOutput();
211
+ expect(
212
+ screen.queryByTestId("exit-fullscreen-output-button"),
213
+ ).not.toBeInTheDocument();
214
+ });
215
+
216
+ it("shows the exit button when the output is the fullscreen element", () => {
217
+ const { container } = renderOutput();
218
+ enterFullscreen(container);
219
+ expect(
220
+ screen.getByTestId("exit-fullscreen-output-button"),
221
+ ).toBeInTheDocument();
222
+ });
223
+
224
+ it("exits fullscreen on click", () => {
225
+ const { container } = renderOutput();
226
+ enterFullscreen(container);
227
+ fireEvent.click(screen.getByTestId("exit-fullscreen-output-button"));
228
+ expect(exitFullscreen).toHaveBeenCalledTimes(1);
229
+ });
230
+
231
+ it("exits fullscreen on Escape", () => {
232
+ const { container } = renderOutput();
233
+ enterFullscreen(container);
234
+ fireEvent.keyDown(document, { key: "Escape" });
235
+ expect(exitFullscreen).toHaveBeenCalledTimes(1);
236
+ });
237
+
238
+ it("ignores Escape outside fullscreen", () => {
239
+ renderOutput();
240
+ fireEvent.keyDown(document, { key: "Escape" });
241
+ expect(exitFullscreen).not.toHaveBeenCalled();
242
+ });
243
+ });