Search

Jump to any page.

Feedback

Alert

Inline message about a page or section, tinted by intent.

pnpm dlx shadcn@latest add @paragon/alert
Brings inclass-variance-authoritycn
registry/paragon/ui/alert.tsx
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "cn"

const alertVariants = cva(
  [
    "group/alert relative grid w-full gap-1 rounded-card border p-4 text-start text-[0.9375rem]",
    "has-data-[slot=alert-action]:pe-24 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-3",
    "*:[svg]:row-span-2 *:[svg]:mt-0.5 *:[svg:not([class*='size-'])]:size-4",
  ],
  {
    variants: {
      variant: {
        default: "border-border bg-card text-card-foreground *:[svg]:text-muted-foreground",
        info: "border-fjord/20 bg-fjord/6 *:[svg]:text-fjord dark:border-fjord/40 dark:bg-fjord/15 dark:*:[svg]:text-[#9db7dc]",
        success:
          "border-oasis/20 bg-oasis/6 *:[svg]:text-oasis dark:border-oasis/40 dark:bg-oasis/15 dark:*:[svg]:text-[#a8cf9f]",
        warning: "border-dune/20 bg-sand/50 *:[svg]:text-dune dark:border-dune/40 dark:bg-dune/12 dark:*:[svg]:text-mangrove",
        destructive: "border-destructive/25 bg-destructive/6 *:[svg]:text-destructive dark:bg-destructive/12",
      },
    },
    defaultVariants: {
      variant: "default",
    },
  }
)

/** An inline message about the page or a section of it. Tinted by intent, never loud. */
function Alert({ className, variant, ...props }: React.ComponentProps<"div"> & VariantProps<typeof alertVariants>) {
  return <div data-slot="alert" role="alert" className={cn(alertVariants({ variant }), className)} {...props} />
}

function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="alert-title"
      className={cn(
        "font-medium tracking-[-0.01em] group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3",
        className
      )}
      {...props}
    />
  )
}

function AlertDescription({ className, ...props }: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="alert-description"
      className={cn(
        "text-sm leading-relaxed text-pretty text-muted-foreground group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-3",
        className
      )}
      {...props}
    />
  )
}

function AlertAction({ className, ...props }: React.ComponentProps<"div">) {
  return <div data-slot="alert-action" className={cn("absolute top-3 end-3", className)} {...props} />
}

export { Alert, AlertTitle, AlertDescription, AlertAction }