"use client"; import React, { useEffect, useState } from "react"; import { cls } from "../util"; import { defaultBorderMixin } from "../styles"; import * as DialogPrimitive from "@radix-ui/react-dialog"; import { usePortalContainer } from "../hooks/PortalContainerContext"; interface SheetProps { children: React.ReactNode; open: boolean; title?: string; modal?: boolean; includeBackgroundOverlay?: boolean; side?: "top" | "bottom" | "left" | "right"; darkBackground?: boolean; transparent?: boolean; onOpenChange?: (open: boolean) => void; className?: string; style?: React.CSSProperties; overlayClassName?: string; overlayStyle?: React.CSSProperties; portalContainer?: HTMLElement | null; } export const Sheet: React.FC = ({ children, side = "right", title, modal = true, includeBackgroundOverlay = true, open, onOpenChange, transparent, className, style, overlayClassName, overlayStyle, portalContainer, ...props }) => { const [displayed, setDisplayed] = useState(false); // Get the portal container from context const contextContainer = usePortalContainer(); // Prioritize manual prop, fallback to context container const finalContainer = (portalContainer ?? contextContainer ?? undefined) as HTMLElement | undefined; useEffect(() => { const timeout = setTimeout(() => { setDisplayed(open); }, 1); return () => clearTimeout(timeout); }, [open]); const transformValue: Record = { top: "-translate-y-full", bottom: "translate-y-full", left: "-translate-x-full", right: "translate-x-full" }; const borderClass: Record = { top: "border-b", bottom: "border-t", left: "border-r", right: "border-l" }; return ( {title ?? "Sheet"} {includeBackgroundOverlay && } event.preventDefault()} className={cls( "outline-none", borderClass[side], defaultBorderMixin, "transform-gpu", "will-change-transform", "text-surface-accent-900 dark:text-white", "fixed transform z-20 transition-all ease-in-out", !displayed ? "duration-150" : "duration-100", "outline-none focus:outline-none", transparent ? "" : "shadow-md bg-white dark:bg-surface-950", side === "top" || side === "bottom" ? "w-full" : "h-full", side === "left" || side === "top" ? "left-0 top-0" : "right-0 bottom-0", displayed && open ? "opacity-100" : "opacity-50", !displayed || !open ? transformValue[side] : "", className )} style={style} > {children} ); };