fumadocs-twoslash
Version:
Typescript Twoslash Integration for Fumadocs
73 lines (72 loc) • 2.24 kB
JavaScript
"use client";
import { createContext, useContext, useMemo, useRef, useState } from "react";
import { Popover } from "@base-ui/react/popover";
import { cn } from "cnfast";
import { jsx } from "react/jsx-runtime";
//#region src/ui/popup.tsx
const PopupContext = createContext(void 0);
function Popup({ delay = 300, children }) {
const [open, setOpen] = useState(false);
const openTimeoutRef = useRef(void 0);
const closeTimeoutRef = useRef(void 0);
return /* @__PURE__ */ jsx(Popover.Root, {
open,
onOpenChange: setOpen,
children: /* @__PURE__ */ jsx(PopupContext.Provider, {
value: useMemo(() => ({
open,
setOpen,
handleOpen(e) {
if (e.pointerType === "touch") return;
if (closeTimeoutRef.current) clearTimeout(closeTimeoutRef.current);
openTimeoutRef.current = window.setTimeout(() => {
setOpen(true);
}, delay);
},
handleClose(e) {
if (e.pointerType === "touch") return;
if (openTimeoutRef.current) clearTimeout(openTimeoutRef.current);
closeTimeoutRef.current = window.setTimeout(() => {
setOpen(false);
}, delay);
}
}), [delay, open]),
children
})
});
}
function PopupTrigger({ children, ...props }) {
const ctx = useContext(PopupContext);
if (!ctx) throw new Error("Missing Popup Context");
return /* @__PURE__ */ jsx(Popover.Trigger, {
onPointerEnter: ctx.handleOpen,
onPointerLeave: ctx.handleClose,
render: (triggerProps) => /* @__PURE__ */ jsx("button", {
...triggerProps,
type: "button",
className: cn("twoslash-hover", triggerProps.className),
children
}),
...props
});
}
function PopupContent({ className, side = "bottom", align = "center", sideOffset = 4, ref, ...props }) {
const ctx = useContext(PopupContext);
if (!ctx) throw new Error("Missing Popup Context");
return /* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsx(Popover.Positioner, {
side,
align,
sideOffset,
children: /* @__PURE__ */ jsx(Popover.Popup, {
ref,
className: cn("fd-twoslash-popover", className),
onPointerEnter: ctx.handleOpen,
onPointerLeave: ctx.handleClose,
initialFocus: false,
finalFocus: false,
...props
})
}) });
}
//#endregion
export { Popup, PopupContent, PopupTrigger };