@marimo-team/islands 0.23.15-dev62 → 0.23.15-dev64
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.
|
@@ -9,7 +9,7 @@ import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
|
|
|
9
9
|
import { dt as kioskModeAtom, ht as outputIsStale } from "./html-to-image-DDENewl2.js";
|
|
10
10
|
import "./chunk-5FQGJX7Z-B9WoXK1R.js";
|
|
11
11
|
import { u as createLucideIcon } from "./dist-B96tMAst.js";
|
|
12
|
-
import { a as DEFAULT_DECK_VERTICAL_ALIGN, c as SlideSidebar, cn as Expand, ct as Panel, dn as Code, i as DEFAULT_DECK_TRANSITION, l as Slide, lt as PanelGroup, o as DEFAULT_SLIDE_TYPE, sn as EyeOff, t as useNotebookCodeAvailable, ut as PanelResizeHandle } from "./code-visibility-
|
|
12
|
+
import { a as DEFAULT_DECK_VERTICAL_ALIGN, c as SlideSidebar, cn as Expand, ct as Panel, dn as Code, i as DEFAULT_DECK_TRANSITION, l as Slide, lt as PanelGroup, o as DEFAULT_SLIDE_TYPE, sn as EyeOff, t as useNotebookCodeAvailable, ut as PanelResizeHandle } from "./code-visibility-YsJOxF8J.js";
|
|
13
13
|
import { X as useDebouncedCallback } from "./input-DStQIuqD.js";
|
|
14
14
|
import "./toDate-B3IRfHhw.js";
|
|
15
15
|
import "./react-dom-BTJzcVJ9.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
import type { JSX, PropsWithChildren } from "react";
|
|
3
3
|
import React from "react";
|
|
4
|
+
import { createPortal } from "react-dom";
|
|
4
5
|
import { z } from "zod";
|
|
5
6
|
import {
|
|
6
7
|
NavigationMenu,
|
|
@@ -9,9 +10,11 @@ import {
|
|
|
9
10
|
NavigationMenuLink,
|
|
10
11
|
NavigationMenuList,
|
|
11
12
|
NavigationMenuTrigger,
|
|
13
|
+
NavigationMenuViewport,
|
|
12
14
|
navigationMenuTriggerStyle,
|
|
13
15
|
} from "@/components/ui/navigation";
|
|
14
16
|
import { Tooltip } from "@/components/ui/tooltip";
|
|
17
|
+
import { useResizeObserver } from "@/hooks/useResizeObserver";
|
|
15
18
|
import { renderHTML } from "@/plugins/core/RenderHTML";
|
|
16
19
|
import { cn } from "@/utils/cn";
|
|
17
20
|
import { appendQueryParams } from "@/utils/urls";
|
|
@@ -21,6 +24,7 @@ import type {
|
|
|
21
24
|
} from "../stateless-plugin";
|
|
22
25
|
import "./navigation-menu.css";
|
|
23
26
|
import { KnownQueryParams } from "@/core/constants";
|
|
27
|
+
import { NavigationMenu as NavigationMenuPrimitive } from "radix-ui";
|
|
24
28
|
|
|
25
29
|
interface MenuItem {
|
|
26
30
|
label: string;
|
|
@@ -45,6 +49,118 @@ interface Data {
|
|
|
45
49
|
orientation: "horizontal" | "vertical";
|
|
46
50
|
}
|
|
47
51
|
|
|
52
|
+
interface PortalPosition {
|
|
53
|
+
left: number;
|
|
54
|
+
top: number;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
interface HorizontalMenuGroupProps {
|
|
58
|
+
item: MenuItemGroup;
|
|
59
|
+
preserveQueryParams: (href: string) => string;
|
|
60
|
+
target: (href: string) => string;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const HorizontalMenuGroup = ({
|
|
64
|
+
item,
|
|
65
|
+
preserveQueryParams,
|
|
66
|
+
target,
|
|
67
|
+
}: HorizontalMenuGroupProps): JSX.Element => {
|
|
68
|
+
const triggerRef = React.useRef<React.ComponentRef<
|
|
69
|
+
typeof NavigationMenuTrigger
|
|
70
|
+
> | null>(null);
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<NavigationMenuPrimitive.Root
|
|
74
|
+
className="relative z-10 max-w-max flex-1 items-center justify-center"
|
|
75
|
+
orientation="horizontal"
|
|
76
|
+
>
|
|
77
|
+
<NavigationMenuList>
|
|
78
|
+
<NavigationMenuItem>
|
|
79
|
+
<NavigationMenuTrigger ref={triggerRef}>
|
|
80
|
+
{renderHTML({ html: item.label })}
|
|
81
|
+
</NavigationMenuTrigger>
|
|
82
|
+
<NavigationMenuContent className="w-auto">
|
|
83
|
+
<ul className="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px] ">
|
|
84
|
+
{item.items.map((subItem) => (
|
|
85
|
+
<ListItem
|
|
86
|
+
key={subItem.label}
|
|
87
|
+
label={subItem.label}
|
|
88
|
+
href={preserveQueryParams(subItem.href)}
|
|
89
|
+
target={target(subItem.href)}
|
|
90
|
+
>
|
|
91
|
+
{subItem.description &&
|
|
92
|
+
renderHTML({ html: subItem.description })}
|
|
93
|
+
</ListItem>
|
|
94
|
+
))}
|
|
95
|
+
</ul>
|
|
96
|
+
</NavigationMenuContent>
|
|
97
|
+
</NavigationMenuItem>
|
|
98
|
+
</NavigationMenuList>
|
|
99
|
+
<NavigationMenuViewportPortal anchorRef={triggerRef}>
|
|
100
|
+
<NavigationMenuViewport />
|
|
101
|
+
</NavigationMenuViewportPortal>
|
|
102
|
+
</NavigationMenuPrimitive.Root>
|
|
103
|
+
);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const NavigationMenuViewportPortal = ({
|
|
107
|
+
anchorRef,
|
|
108
|
+
children,
|
|
109
|
+
}: PropsWithChildren<{
|
|
110
|
+
anchorRef: React.RefObject<HTMLElement | null>;
|
|
111
|
+
}>): React.ReactElement | null => {
|
|
112
|
+
const [position, setPosition] = React.useState<PortalPosition | null>(null);
|
|
113
|
+
|
|
114
|
+
const updatePosition = React.useCallback(() => {
|
|
115
|
+
if (!anchorRef.current) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const rect = anchorRef.current.getBoundingClientRect();
|
|
120
|
+
setPosition({
|
|
121
|
+
left: rect.left,
|
|
122
|
+
top: rect.bottom,
|
|
123
|
+
});
|
|
124
|
+
}, [anchorRef]);
|
|
125
|
+
|
|
126
|
+
React.useLayoutEffect(() => {
|
|
127
|
+
updatePosition();
|
|
128
|
+
}, [updatePosition]);
|
|
129
|
+
|
|
130
|
+
useResizeObserver({
|
|
131
|
+
ref: anchorRef,
|
|
132
|
+
onResize: updatePosition,
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
React.useEffect(() => {
|
|
136
|
+
if (typeof window === "undefined") {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
window.addEventListener("resize", updatePosition);
|
|
141
|
+
document.addEventListener("scroll", updatePosition, { capture: true });
|
|
142
|
+
|
|
143
|
+
return () => {
|
|
144
|
+
window.removeEventListener("resize", updatePosition);
|
|
145
|
+
document.removeEventListener("scroll", updatePosition, { capture: true });
|
|
146
|
+
};
|
|
147
|
+
}, [updatePosition]);
|
|
148
|
+
|
|
149
|
+
if (!position || typeof document === "undefined") {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return createPortal(
|
|
154
|
+
<div
|
|
155
|
+
className="fixed z-50"
|
|
156
|
+
style={{ left: position.left, top: position.top }}
|
|
157
|
+
>
|
|
158
|
+
{children}
|
|
159
|
+
</div>,
|
|
160
|
+
document.body,
|
|
161
|
+
);
|
|
162
|
+
};
|
|
163
|
+
|
|
48
164
|
export class NavigationMenuPlugin implements IStatelessPlugin<Data> {
|
|
49
165
|
tagName = "marimo-nav-menu";
|
|
50
166
|
|
|
@@ -109,30 +225,12 @@ const NavMenuComponent = ({
|
|
|
109
225
|
const renderMenuItem = (item: MenuItem | MenuItemGroup) => {
|
|
110
226
|
if ("items" in item) {
|
|
111
227
|
return orientation === "horizontal" ? (
|
|
112
|
-
<
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
<NavigationMenuContent>
|
|
119
|
-
<ul className="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px] ">
|
|
120
|
-
{item.items.map((subItem) => (
|
|
121
|
-
<ListItem
|
|
122
|
-
key={subItem.label}
|
|
123
|
-
label={subItem.label}
|
|
124
|
-
href={preserveQueryParams(subItem.href)}
|
|
125
|
-
target={target(subItem.href)}
|
|
126
|
-
>
|
|
127
|
-
{subItem.description &&
|
|
128
|
-
renderHTML({ html: subItem.description })}
|
|
129
|
-
</ListItem>
|
|
130
|
-
))}
|
|
131
|
-
</ul>
|
|
132
|
-
</NavigationMenuContent>
|
|
133
|
-
</NavigationMenuItem>
|
|
134
|
-
</NavigationMenuList>
|
|
135
|
-
</NavigationMenu>
|
|
228
|
+
<HorizontalMenuGroup
|
|
229
|
+
key={item.label}
|
|
230
|
+
item={item}
|
|
231
|
+
preserveQueryParams={preserveQueryParams}
|
|
232
|
+
target={target}
|
|
233
|
+
/>
|
|
136
234
|
) : (
|
|
137
235
|
<NavigationMenuItem key={item.label}>
|
|
138
236
|
<div
|
|
@@ -196,32 +294,30 @@ const NavMenuComponent = ({
|
|
|
196
294
|
};
|
|
197
295
|
|
|
198
296
|
const ListItem = React.forwardRef<
|
|
199
|
-
React.
|
|
297
|
+
React.ComponentRef<"a">,
|
|
200
298
|
React.ComponentPropsWithoutRef<"a"> & {
|
|
201
299
|
label: string;
|
|
202
300
|
}
|
|
203
301
|
>(({ className, label, children, ...props }, ref) => {
|
|
204
302
|
return (
|
|
205
303
|
<li>
|
|
206
|
-
<
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
>
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
</a>
|
|
224
|
-
</NavigationMenuLink>
|
|
304
|
+
<a
|
|
305
|
+
ref={ref}
|
|
306
|
+
className={cn(
|
|
307
|
+
"block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-hidden transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground",
|
|
308
|
+
className,
|
|
309
|
+
)}
|
|
310
|
+
{...props}
|
|
311
|
+
>
|
|
312
|
+
<div className="text-base font-medium leading-none">
|
|
313
|
+
{renderHTML({ html: label })}
|
|
314
|
+
</div>
|
|
315
|
+
{children && (
|
|
316
|
+
<p className="line-clamp-2 text-sm leading-snug text-muted-foreground">
|
|
317
|
+
{children}
|
|
318
|
+
</p>
|
|
319
|
+
)}
|
|
320
|
+
</a>
|
|
225
321
|
</li>
|
|
226
322
|
);
|
|
227
323
|
});
|