/** * @factory/ui — Dialog (Radix `@radix-ui/react-dialog` wrapper). * * Close-on-Escape, scroll lock and the FOCUS TRAP are delegated to Radix — * we do NOT re-implement trapping here (see src/focus.ts for non-Radix * surfaces). All colors via `var(--…)` tokens. */ import * as React from "react"; import * as RadixDialog from "@radix-ui/react-dialog"; import { clsx } from "clsx"; export const Dialog = RadixDialog.Root; export const DialogTrigger = RadixDialog.Trigger; export const DialogClose = RadixDialog.Close; export const DialogContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( {children} ✕Close )); DialogContent.displayName = "DialogContent"; export const DialogHeader = ({ className, ...props }: React.HTMLAttributes) => (
); export const DialogTitle = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); DialogTitle.displayName = "DialogTitle"; export const DialogDescription = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); DialogDescription.displayName = "DialogDescription"; export const DialogFooter = ({ className, ...props }: React.HTMLAttributes) => (
); /** * Minimal dialog lifecycle state for controlled usage. * Radix animates open/close; we track the logical phase: * "closed" → (openDialog) → "open" → (closeDialog) → "closing" → "closed". * The "closing" phase is released by the `onAnimationEnd`/unmount timing in * the wiring — kept as a documented simple model here. */ export function useDialogState() { const [state, setState] = React.useState<"closed" | "open" | "closing">("closed"); const [open, setOpen] = React.useState(false); const openDialog = React.useCallback(() => { setOpen(true); setState("open"); }, []); const closeDialog = React.useCallback(() => { setOpen(false); setState("closing"); }, []); /** Called by the wiring after Radix finishes the exit animation. */ const onAnimationEnd = React.useCallback(() => { setState("closed"); }, []); return { open, openDialog, closeDialog, state, onAnimationEnd } as const; }