import * as ModalPrimitive from '@radix-ui/react-dialog' import { cva, type VariantProps } from 'class-variance-authority' import type React from 'react' import { SvgDelete1 } from '@chainlink/blocks-icons' import { cn } from '../../utils' import { Typography } from '../Typography' /** * Root state container for a modal dialog. Manages open/closed state. * Compose with ModalTrigger and ModalContent. */ const Modal = ModalPrimitive.Root Modal.displayName = 'Modal' /** Element that opens the modal when interacted with. Use `asChild` to make any element the trigger. */ const ModalTrigger = ModalPrimitive.Trigger ModalTrigger.displayName = 'ModalTrigger' /** Portal that renders ModalContent outside the DOM tree. Used internally by ModalContent. */ const ModalPortal = ModalPrimitive.Portal ModalPortal.displayName = 'ModalPortal' /** Primitive close control. Use `asChild` to make any element close the modal. For a styled close button, use ModalCloseButton. */ const ModalClose = ModalPrimitive.Close ModalClose.displayName = 'ModalClose' type ModalCloseButtonProps = React.ComponentPropsWithoutRef< typeof ModalPrimitive.Close > & { ref?: React.Ref> } /** * Styled circular close button (X icon) for use inside ModalContent. Already * rendered automatically by ModalContent unless `showCloseButton={false}`. * Use this manually when you need a close button in a custom layout. */ const ModalCloseButton = ({ className, children, asChild, ref, ...props }: ModalCloseButtonProps) => ( {asChild ? ( children ) : ( <> {children || ( )} Close )} ) ModalCloseButton.displayName = 'ModalCloseButton' type ModalOverlayProps = React.ComponentPropsWithoutRef< typeof ModalPrimitive.Overlay > & { ref?: React.Ref> } const ModalOverlay = ({ className, ref, ...props }: ModalOverlayProps) => ( ) ModalOverlay.displayName = 'ModalOverlay' const modalContentVariants = cva( 'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-0 border bg-background p-0 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg', { variants: { size: { default: 'max-w-3xl', sm: 'max-w-xl', lg: 'max-w-5xl', }, }, defaultVariants: { size: 'default', }, }, ) type ModalContentProps = React.ComponentPropsWithoutRef< typeof ModalPrimitive.Content > & VariantProps & { /** Controls the maximum width of the modal panel. Defaults to `default` (max-w-3xl). */ size?: 'default' | 'sm' | 'lg' /** When false, hides the default ModalCloseButton. Use when you need a custom close layout. Defaults to true. */ showCloseButton?: boolean /** Additional className for the overlay (backdrop). */ overlayClassName?: string ref?: React.Ref> } /** * Main dialog panel. Renders inside a portal with a backdrop overlay. * Includes a close button by default. Compose with ModalHeader, ModalBody, * and ModalFooter. */ const ModalContent = ({ className, overlayClassName, children, size, showCloseButton = true, ref, ...props }: ModalContentProps) => ( {children} {showCloseButton && } ) ModalContent.displayName = 'ModalContent' type ModalHeaderProps = React.HTMLAttributes & { /** When true, renders a bottom border between the header and the modal body. */ showDivider?: boolean } /** Top section of the modal panel. Contains ModalTitle and optionally ModalDescription. */ const ModalHeader = ({ className, showDivider = false, ...props }: ModalHeaderProps) => (
) ModalHeader.displayName = 'ModalHeader' type ModalFooterProps = React.HTMLAttributes & { /** When true, renders a top border between the modal body and the footer. */ showDivider?: boolean } /** Bottom section of the modal panel. Lays out action buttons right-aligned in a row. */ const ModalFooter = ({ className, showDivider = false, ...props }: ModalFooterProps) => (
) ModalFooter.displayName = 'ModalFooter' type ModalTitleProps = React.ComponentPropsWithoutRef< typeof ModalPrimitive.Title > & { ref?: React.Ref> } /** Accessible dialog title. Rendered as an `
` via Typography. Required for screen reader announcements. */ const ModalTitle = ({ className, ref, ...props }: ModalTitleProps) => ( {props.children} ) ModalTitle.displayName = 'ModalTitle' type ModalDescriptionProps = React.ComponentPropsWithoutRef< typeof ModalPrimitive.Description > & { ref?: React.Ref> } /** Optional accessible description below the modal title. Announced by screen readers when the dialog opens. */ const ModalDescription = ({ className, ref, ...props }: ModalDescriptionProps) => (
{props.children}
) ModalDescription.displayName = 'ModalDescription' /** Scrollable content area between ModalHeader and ModalFooter. */ const ModalBody = ({ className, ...props }: React.HTMLAttributes) => (
) ModalBody.displayName = 'ModalBody' export { Modal, ModalPortal, ModalOverlay, ModalClose, ModalCloseButton, ModalTrigger, ModalContent, ModalHeader, ModalFooter, ModalTitle, ModalDescription, ModalBody, }