import { cva, VariantProps } from 'class-variance-authority'; import * as React from 'react'; import { cn, ComponentAnatomy, defineStyleAnatomy } from '../core/styling'; /* ------------------------------------------------------------------------------------------------- * Anatomy * -----------------------------------------------------------------------------------------------*/ export const AlertAnatomy = defineStyleAnatomy({ root: cva( ['UI-Alert__root', 'py-3 px-4 flex justify-between rounded-[--radius]'], { variants: { intent: { info: 'bg-blue-50 text-blue-500 dark:bg-opacity-10 dark:text-blue-200', success: 'bg-green-50 text-green-500 dark:bg-opacity-10 dark:text-green-200', warning: 'bg-orange-50 text-orange-500 dark:bg-opacity-10 dark:text-orange-200', alert: 'bg-red-50 text-red-500 dark:bg-opacity-10 dark:text-red-200', 'info-basic': 'bg-white text-gray-800 border dark:bg-gray-800 dark:text-gray-200', 'success-basic': 'bg-white text-gray-800 border dark:bg-gray-800 dark:text-gray-200', 'warning-basic': 'bg-white text-gray-800 border dark:bg-gray-800 dark:text-gray-200', 'alert-basic': 'bg-white text-gray-800 border dark:bg-gray-800 dark:text-gray-200', }, }, defaultVariants: { intent: 'info', }, } ), detailsContainer: cva(['UI-Alert__detailsContainer', 'flex']), textContainer: cva([ 'UI-Alert__textContainer', 'flex flex-col self-center ml-3 gap-.5', ]), title: cva(['UI-Alert__title', 'font-bold']), description: cva(['UI-Alert__description']), icon: cva(['UI-Alert__icon', 'text-2xl content-evenly'], { variants: { intent: { 'info-basic': 'text-blue-500', 'success-basic': 'text-green-500', 'warning-basic': 'text-orange-500', 'alert-basic': 'text-red-500', info: 'text-blue-500', success: 'text-green-500', warning: 'text-orange-500', alert: 'text-red-500', }, }, defaultVariants: { intent: 'info-basic', }, }), closeButton: cva([ 'UI-Alert__closeButton', 'flex-none self-start text-2xl hover:opacity-50 transition ease-in cursor-pointer h-5 w-5', ]), }); /* ------------------------------------------------------------------------------------------------- * Alert * -----------------------------------------------------------------------------------------------*/ export type AlertProps = React.ComponentPropsWithRef<'div'> & VariantProps & ComponentAnatomy & { /** * The title of the alert */ title?: string; /** * The description text or content of the alert */ description?: React.ReactNode; /** * Replace the default icon with a custom icon * * - `iconClass` does not apply to custom icons */ icon?: React.ReactNode; /** * If true, a close button will be rendered */ isClosable?: boolean; /** * Callback invoked when the close button is clicked */ onClose?: () => void; }; export const Alert = React.forwardRef( (props, ref) => { const { children, className, title, description, isClosable, onClose, intent = 'info-basic', iconClass, detailsContainerClass, textContainerClass, titleClass, descriptionClass, closeButtonClass, icon, ...rest } = props; let Icon: any = null; if (intent === 'info-basic' || intent === 'info') { Icon = ( ); } else if (intent === 'alert-basic' || intent === 'alert') { Icon = ( ); } else if (intent === 'warning-basic' || intent === 'warning') { Icon = ( ); } else if (intent === 'success-basic' || intent === 'success') { Icon = ( ); } return (
{icon ? ( icon ) : (
{Icon && Icon}
)}
{title} {!!(description || children) && (
{description || children}
)}
{onClose && ( )}
); } ); Alert.displayName = 'Alert';