@marimo-team/islands 0.25.3-dev237 → 0.25.3-dev239

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/islands",
3
- "version": "0.25.3-dev237",
3
+ "version": "0.25.3-dev239",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -1,8 +1,50 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
- import { act, render } from "@testing-library/react";
2
+ import { act, render, renderHook } from "@testing-library/react";
3
3
  import { useRef } from "react";
4
4
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
5
- import { useIsFullScreen } from "../fullscreen";
5
+ import { useFullScreenClass, useIsFullScreen } from "../fullscreen";
6
+
7
+ describe("useFullScreenClass", () => {
8
+ let fullscreenElement: Element | null = null;
9
+
10
+ beforeEach(() => {
11
+ fullscreenElement = null;
12
+ Object.defineProperty(document, "fullscreenElement", {
13
+ configurable: true,
14
+ get: () => fullscreenElement,
15
+ });
16
+ });
17
+
18
+ afterEach(() => {
19
+ Reflect.deleteProperty(document, "fullscreenElement");
20
+ document.documentElement.classList.remove("marimo-fullscreen");
21
+ });
22
+
23
+ it("reflects fullscreen state at mount and on entry and exit", () => {
24
+ fullscreenElement = document.body;
25
+ const { unmount } = renderHook(useFullScreenClass);
26
+ expect(document.documentElement).toHaveClass("marimo-fullscreen");
27
+
28
+ fullscreenElement = null;
29
+ act(() => document.dispatchEvent(new Event("fullscreenchange")));
30
+ expect(document.documentElement).not.toHaveClass("marimo-fullscreen");
31
+
32
+ fullscreenElement = document.body;
33
+ act(() => document.dispatchEvent(new Event("fullscreenchange")));
34
+ expect(document.documentElement).toHaveClass("marimo-fullscreen");
35
+ unmount();
36
+ });
37
+
38
+ it("removes the class and listener on unmount", () => {
39
+ fullscreenElement = document.body;
40
+ const { unmount } = renderHook(useFullScreenClass);
41
+ unmount();
42
+ expect(document.documentElement).not.toHaveClass("marimo-fullscreen");
43
+
44
+ act(() => document.dispatchEvent(new Event("fullscreenchange")));
45
+ expect(document.documentElement).not.toHaveClass("marimo-fullscreen");
46
+ });
47
+ });
6
48
 
7
49
  const FullScreenFlag = ({ label }: { label: string }) => {
8
50
  const ref = useRef<HTMLDivElement>(null);
@@ -4,7 +4,12 @@ import type { Popover } from "radix-ui";
4
4
 
5
5
  type PopoverContentProps = Popover.PopoverContentProps;
6
6
 
7
- import React, { type RefObject, useState, useSyncExternalStore } from "react";
7
+ import React, {
8
+ type RefObject,
9
+ useLayoutEffect,
10
+ useState,
11
+ useSyncExternalStore,
12
+ } from "react";
8
13
  import { isInVscodeExtension } from "@/core/vscode/is-in-vscode";
9
14
  import { useEventListener } from "@/hooks/useEventListener";
10
15
 
@@ -14,6 +19,25 @@ const VSCODE_OUTPUT_CONTAINER_SELECTOR = "[data-vscode-output-container]";
14
19
  // Otherwise, we give a 30px buffer to the max-height.
15
20
  export const MAX_HEIGHT_OFFSET = isInVscodeExtension() ? 0 : 30;
16
21
 
22
+ // An explicit class avoids document-wide :has(:fullscreen) style invalidation.
23
+ export function useFullScreenClass() {
24
+ useLayoutEffect(() => {
25
+ const syncFullScreenClass = () => {
26
+ document.documentElement.classList.toggle(
27
+ "marimo-fullscreen",
28
+ Boolean(document.fullscreenElement),
29
+ );
30
+ };
31
+
32
+ syncFullScreenClass();
33
+ document.addEventListener("fullscreenchange", syncFullScreenClass);
34
+ return () => {
35
+ document.removeEventListener("fullscreenchange", syncFullScreenClass);
36
+ document.documentElement.classList.remove("marimo-fullscreen");
37
+ };
38
+ }, []);
39
+ }
40
+
17
41
  /**
18
42
  * Get the full screen element if we are in full screen mode
19
43
  */
@@ -7,6 +7,7 @@ import { Provider as SlotzProvider } from "@marimo-team/react-slotz";
7
7
  import type React from "react";
8
8
  import { memo, type PropsWithChildren, Suspense } from "react";
9
9
  import { TailwindIndicator } from "@/components/debug/indicator";
10
+ import { useFullScreenClass } from "@/components/ui/fullscreen";
10
11
  import { useAppConfig, useResolvedMarimoConfig } from "@/core/config/config";
11
12
  import { getInitialAppMode } from "@/core/mode";
12
13
  import { CssVariables } from "@/theme/ThemeProvider";
@@ -58,6 +59,7 @@ export function preloadPage(mode: string) {
58
59
  * The root component of the Marimo app.
59
60
  */
60
61
  export const MarimoApp: React.FC = memo(() => {
62
+ useFullScreenClass();
61
63
  const [userConfig] = useResolvedMarimoConfig();
62
64
  const appConfig = useAppConfig();
63
65
  const editorFontSize = toRem(userConfig.display.code_editor_font_size);
@@ -31,7 +31,7 @@
31
31
  }
32
32
 
33
33
  /* When any element is fullscreen, hide the element with this class */
34
- :root:has(:fullscreen) .hide-on-fullscreen {
34
+ :root.marimo-fullscreen .hide-on-fullscreen {
35
35
  display: none !important;
36
36
  }
37
37