"use client"; import Image, { type StaticImageData } from "next/image"; import type { HTMLAttributes, ReactNode } from "react"; import { useEffect, useState } from "react"; import Button from "./button"; import { LoadingSkeleton } from "./loading-skeleton"; import { useI18n } from "@/translations/provider"; const EXIT_ANIMATION_MS = 220; type InformationSheetPresetIcon = | "play" | "warning" | "coin" | "check" | "stash_play-solid.svg" | "warning.svg" | "coin.svg" | "Vectorcheck.svg"; type InformationSheetIcon = | InformationSheetPresetIcon | string | { src: string | StaticImageData; alt?: string; width?: number; height?: number; }; export type InformationSheetProps = Omit< HTMLAttributes, "children" | "title" > & { icon?: InformationSheetIcon | null; title?: ReactNode | ((controls: { close: () => void }) => ReactNode); description?: ReactNode; buttons?: ReactNode | ((controls: { close: () => void }) => ReactNode); closeOnOutside?: boolean; onClose?: () => void; isLoading?: boolean; }; const DEFAULT_ICON = { src: "/assets/images/stash_play-solid.svg", alt: "Play", width: 50, height: 50, } as const; const ICON_PRESETS: Record< InformationSheetPresetIcon, { src: string; alt: string; width: number; height: number; } > = { play: DEFAULT_ICON, "stash_play-solid.svg": DEFAULT_ICON, warning: { src: "/assets/images/Vector.svg", alt: "Warning", width: 36, height: 36, }, "warning.svg": { src: "/assets/images/Vector.svg", alt: "Warning", width: 36, height: 36, }, coin: { src: "/assets/images/Inner Plugdsain Iframe.svg", alt: "Coin", width: 50, height: 50, }, "coin.svg": { src: "/assets/images/Inner Plugdsain Iframe.svg", alt: "Coin", width: 50, height: 50, }, check: { src: "/assets/images/Vectofdasr.svg", alt: "Check", width: 36, height: 36, }, "Vectorcheck.svg": { src: "/assets/images/Vectorcheck.svg", alt: "Check", width: 36, height: 36, }, }; function resolveIcon(icon: InformationSheetIcon | null | undefined) { if (icon === null) { return null; } if (!icon) { return DEFAULT_ICON; } if (typeof icon === "string") { return ( ICON_PRESETS[icon as InformationSheetPresetIcon] ?? { src: icon, alt: "Information", width: DEFAULT_ICON.width, height: DEFAULT_ICON.height, } ); } return { src: icon.src, alt: icon.alt ?? "Information", width: icon.width ?? DEFAULT_ICON.width, height: icon.height ?? DEFAULT_ICON.height, }; } export function InformationSheet({ icon, title, description, buttons, closeOnOutside = true, onClose, className, isLoading = false, ...props }: InformationSheetProps) { const { locale, dictionary: t } = useI18n(); const isRtl = locale === "fa" || locale === "ar" || locale === "ur" || locale === "he" || locale === "ks"; const [isVisible, setIsVisible] = useState(true); const [isEntering, setIsEntering] = useState(true); const [isClosing, setIsClosing] = useState(false); const resolvedIcon = resolveIcon(icon); const closeSheet = () => { if (isClosing) { return; } setIsClosing(true); }; const controls = { close: closeSheet }; const resolvedTitle = typeof title === "function" ? title(controls) : title; const resolvedButtons = typeof buttons === "string" ? ( ) : typeof buttons === "function" ? ( buttons(controls) ) : ( buttons ); useEffect(() => { const frameId = window.requestAnimationFrame(() => { setIsEntering(false); }); return () => { window.cancelAnimationFrame(frameId); }; }, []); useEffect(() => { if (!isVisible) { return; } const previousBodyOverflow = document.body.style.overflow; const previousHtmlOverflow = document.documentElement.style.overflow; document.body.style.overflow = "hidden"; document.documentElement.style.overflow = "hidden"; return () => { document.body.style.overflow = previousBodyOverflow; document.documentElement.style.overflow = previousHtmlOverflow; }; }, [isVisible]); useEffect(() => { if (!isClosing) { return; } const timeoutId = window.setTimeout(() => { setIsVisible(false); onClose?.(); }, EXIT_ANIMATION_MS); return () => { window.clearTimeout(timeoutId); }; }, [isClosing, onClose]); if (!isVisible) { return null; } return (
{ if (closeOnOutside && event.target === event.currentTarget) { closeSheet(); } }} onKeyDown={(event) => { if ( closeOnOutside && event.target === event.currentTarget && (event.key === "Escape" || event.key === "Enter" || event.key === " ") ) { event.preventDefault(); closeSheet(); } }} >
{isLoading ? ( <>
) : ( <> {resolvedIcon ? ( {resolvedIcon.alt} ) : null}

{resolvedTitle}

{description ? (
{description}
) : null} {resolvedButtons ? (
{resolvedButtons}
) : null} )}
); } export default InformationSheet;