{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "alert",
  "title": "Alert",
  "author": "AniBT <https://anibt.net>",
  "description": "AniBT notice: a note on the state's wash (info blue, success mint, warning amber, destructive red) with the icon in the state's ink, or the inline row form with a leading dot; AlertAction for a retry.",
  "dependencies": [
    "class-variance-authority"
  ],
  "registryDependencies": [
    "@anibt/theme"
  ],
  "files": [
    {
      "path": "registry/anibt/ui/alert.tsx",
      "content": "import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\n/**\n * Alert — an AniBT 「贴纸手账」 notice.\n *\n * A note on the state's wash: radius 10, a 1px edge in the state's line, 13px\n * copy, and the icon (an `svg` as the first child, as in shadcn) in the\n * state's ink. One job per colour: `info` is blue (time, in progress),\n * `success` mint, `warning` amber, `destructive` red; `default` is neutral.\n * Pink never marks a notice — it is for actions.\n *\n * `inline` draws the site's row form instead: no fill, a 1px rule above and\n * below, and a 6px dot in the state's colour leading the line — for a notice\n * that is a line of a form or a list rather than a box on the page. The words\n * must say the state on their own; colour never speaks alone.\n *\n * `role=\"alert\"` is the default; pass `role=\"status\"` for a notice that is\n * not urgent. `AlertAction` holds a button at the top-right.\n */\nconst alertVariants = cva(\n  \"group/alert relative grid w-full grid-cols-[minmax(0,1fr)] items-start gap-x-2.5 gap-y-0.5 text-left text-[13px] leading-[1.6] has-data-[slot=alert-action]:pr-24 [&>svg]:pointer-events-none [&>svg]:row-span-2 [&>svg]:mt-[3px] [&>svg:not([class*='size-'])]:size-4\",\n  {\n    variants: {\n      variant: {\n        default: \"\",\n        info: \"\",\n        success: \"\",\n        warning: \"\",\n        destructive: \"\",\n      },\n      inline: {\n        false:\n          \"rounded-[10px] px-3.5 py-2.5 has-[>svg]:grid-cols-[16px_minmax(0,1fr)]\",\n        true:\n          \"border-y border-border px-0 py-2 text-anibt-ink2 grid-cols-[6px_minmax(0,1fr)] before:row-span-2 before:mt-[8px] before:size-1.5 before:rounded-full before:content-[''] [&>svg]:hidden\",\n      },\n    },\n    compoundVariants: [\n      { inline: false, variant: \"default\", class: \"bg-muted text-foreground shadow-[inset_0_0_0_1px_var(--border)] [&>svg]:text-muted-foreground\" },\n      { inline: false, variant: \"info\", class: \"bg-anibt-time-wash text-foreground shadow-[inset_0_0_0_1px_var(--anibt-time-line)] [&>svg]:text-anibt-time-ink *:data-[slot=alert-title]:text-anibt-time-ink\" },\n      { inline: false, variant: \"success\", class: \"bg-anibt-ok-wash text-foreground shadow-[inset_0_0_0_1px_color-mix(in_srgb,var(--anibt-ok-fill)_40%,transparent)] [&>svg]:text-anibt-ok *:data-[slot=alert-title]:text-anibt-ok\" },\n      { inline: false, variant: \"warning\", class: \"bg-anibt-warn-wash text-foreground shadow-[inset_0_0_0_1px_color-mix(in_srgb,var(--anibt-warn-fill)_45%,transparent)] [&>svg]:text-anibt-warn *:data-[slot=alert-title]:text-anibt-warn\" },\n      { inline: false, variant: \"destructive\", class: \"bg-anibt-danger-wash text-foreground shadow-[inset_0_0_0_1px_var(--anibt-danger-line)] [&>svg]:text-destructive *:data-[slot=alert-title]:text-destructive\" },\n      { inline: true, variant: \"default\", class: \"before:bg-muted-foreground\" },\n      { inline: true, variant: \"info\", class: \"before:bg-anibt-time\" },\n      { inline: true, variant: \"success\", class: \"before:bg-anibt-ok-fill\" },\n      { inline: true, variant: \"warning\", class: \"before:bg-anibt-warn-fill\" },\n      { inline: true, variant: \"destructive\", class: \"before:bg-anibt-danger-fill\" },\n    ],\n    defaultVariants: {\n      variant: \"default\",\n      inline: false,\n    },\n  }\n)\n\ntype AlertProps = React.ComponentProps<\"div\"> & VariantProps<typeof alertVariants>\n\nfunction Alert({ className, variant, inline, ...props }: AlertProps) {\n  return (\n    <div\n      data-slot=\"alert\"\n      data-variant={variant ?? \"default\"}\n      data-inline={inline ? \"true\" : undefined}\n      role=\"alert\"\n      className={cn(alertVariants({ variant, inline }), className)}\n      {...props}\n    />\n  )\n}\n\n/** 13/700; takes the state's ink on a tinted alert. */\nfunction AlertTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"alert-title\"\n      className={cn(\n        \"col-start-auto font-bold text-foreground group-has-[>svg]/alert:col-start-2 group-data-[inline=true]/alert:col-start-2\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction AlertDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"alert-description\"\n      className={cn(\n        \"grid justify-items-start gap-1 text-anibt-ink2 group-has-[>svg]/alert:col-start-2 group-data-[inline=true]/alert:col-start-2 [&_a]:font-semibold [&_a]:text-accent-foreground [&_a]:underline-offset-4 [&_a:hover]:underline [&_p]:leading-relaxed\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\n/** A button at the top-right of the notice (retry, dismiss). */\nfunction AlertAction({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"alert-action\"\n      className={cn(\n        \"absolute top-2 right-2 flex items-center gap-1 group-data-[inline=true]/alert:top-1.5 group-data-[inline=true]/alert:right-0\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Alert, AlertTitle, AlertDescription, AlertAction, alertVariants }\nexport type { AlertProps }\n",
      "type": "registry:ui"
    }
  ],
  "categories": [
    "feedback"
  ],
  "type": "registry:ui"
}