wip: added project modal
still want to add carousel, summary, etc.
This commit is contained in:
38
frontend/islands/portal.tsx
Normal file
38
frontend/islands/portal.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
import { createPortal } from "preact/compat";
|
||||
import type { ComponentChildren } from "preact";
|
||||
|
||||
type PortalProps = {
|
||||
into?: string | HTMLElement;
|
||||
children: ComponentChildren;
|
||||
};
|
||||
|
||||
export function Portal({ into = "body", children }: PortalProps) {
|
||||
const [host, setHost] = useState<HTMLElement | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof document === "undefined") return;
|
||||
|
||||
let target: HTMLElement | null = null;
|
||||
if (typeof into === "string") {
|
||||
target = into === "body" ? document.body : document.querySelector(into);
|
||||
} else {
|
||||
target = into;
|
||||
}
|
||||
|
||||
if (!target) target = document.body;
|
||||
|
||||
const wrapper = document.createElement("div");
|
||||
wrapper.className = "preact-portal-root";
|
||||
target.appendChild(wrapper);
|
||||
setHost(wrapper);
|
||||
|
||||
return () => {
|
||||
if (wrapper.parentNode) wrapper.parentNode.removeChild(wrapper);
|
||||
setHost(null);
|
||||
};
|
||||
}, [into]);
|
||||
|
||||
if (!host) return null;
|
||||
return createPortal(children, host);
|
||||
}
|
||||
Reference in New Issue
Block a user