import { cloneElement, isValidElement, lazy, Suspense, useState, type MouseEvent, type ReactElement, type ReactNode, } from 'react'; import type { Event } from 'nostr-tools'; /** * Lightweight zap trigger. * * The full ZapDialog pulls in the Cashu wallet stack (`useCashu`, mint repos, * token operations) — several hundred KB that used to land in the initial * bundle because every SpotCard rendered a ZapButton. This wrapper keeps only * the trigger in the entry chunk and loads the actual dialog on first tap. */ const LoadedZapDialog = lazy(() => import('@/components/ZapDialog').then((m) => ({ default: m.ZapDialog })), ); interface LazyZapDialogProps { target: Event; children: ReactNode; className?: string; } export function LazyZapDialog({ target, children, className }: LazyZapDialogProps) { const [open, setOpen] = useState(false); const handleClick = (event: MouseEvent) => { if (isValidElement(children)) { const child = children as ReactElement<{ onClick?: (event: MouseEvent) => void }>; child.props.onClick?.(event); } setOpen(true); }; const trigger = isValidElement(children) ? ( cloneElement( children as ReactElement<{ onClick?: (event: MouseEvent) => void; className?: string }>, { onClick: handleClick, className: [ (children as ReactElement<{ className?: string }>).props.className, 'cursor-pointer', ].filter(Boolean).join(' '), }, ) ) : (
{children}
); return ( <> {trigger} {open && ( )} ); }