Primitives
Alert
BetaBeta — the props contract is close to final, but small breaking changes can still land.Inline status panel for callouts, errors, and notices.
Composition
Anatomy
- <Alert>
- <AlertTitle />
- <AlertDescription />
Installation
First install and activate one skin. Core deliberately contains no visual token defaults.
The Control UI source installs this primitive from src/registry/sources/control-ui/ui/alert.tsx.
npx shadcn@latest add https://control-ui.dev/r/alert.jsonRaw code
Primary installed source
"use client";import { useRender } from "@base-ui/react/use-render";import type { ComponentProps, CSSProperties } from "react";import type { RenderProp } from "@/components/control-ui/control-props";import type { AlertKnobStyle } from "@/components/control-ui/knob-contracts/alert-knobs";import { cn } from "@/components/control-ui/lib/cn";export const alertVariants = ["default", "destructive"] as const;export type AlertVariant = (typeof alertVariants)[number];export type AlertProps = Omit<ComponentProps<"div">, "style"> & { style?: CSSProperties & AlertKnobStyle } & { variant?: AlertVariant };export type AlertTitleProps = Omit<ComponentProps<"div">, "style"> & { render?: RenderProp<ComponentProps<"div">>; style?: CSSProperties & AlertKnobStyle;};export type AlertDescriptionProps = Omit<ComponentProps<"div">, "style"> & { style?: CSSProperties & AlertKnobStyle };export function Alert({ variant = "default", className, ...props }: AlertProps) { return ( <div role={variant === "destructive" ? "alert" : "status"} data-control-ui="alert" data-control-family="alert" data-slot="root" data-surface="panel" data-variant={variant} className={cn("relative grid w-full items-start", className)} {...props} /> );}export function AlertTitle({ render, className, ...props }: AlertTitleProps) { return useRender({ defaultTagName: "div", render, props: { ...props, "data-control-ui": "alert", "data-control-family": "alert", "data-slot": "title", className: cn("col-start-2 min-w-0", className), }, });}export function AlertDescription({ className, ...props }: AlertDescriptionProps) { return ( <div data-control-ui="alert" data-control-family="alert" data-slot="description" className={cn("col-start-2 grid min-w-0 justify-items-start", className)} {...props} /> );}Knobs
Typed custom properties the recipe paints with. Set one on the root — style, a utility class, or a skin — and every slot inherits it.
--cui-alert-* · 15 knobsHow the cascade resolves--cui-alert-radius<length-percentage>var(--radius-lg)--cui-alert-background<color>var(--card)--cui-alert-border-color<color>var(--border)--cui-alert-shadow*none--cui-alert-foreground<color>var(--card-foreground)--cui-alert-description-foreground<color>var(--muted-foreground)--cui-alert-border-width<length>var(--control-rim-width)--cui-alert-padding<length-percentage>calc(var(--spacing) * 3)--cui-alert-padding-inline<length-percentage>calc(var(--spacing) * 4)--cui-alert-gap<length-percentage>calc(var(--spacing) * 0.5)--cui-alert-icon-gap<length-percentage>calc(var(--spacing) * 3)--cui-alert-icon-size<length-percentage>calc(var(--spacing) * 4)--cui-alert-font-size<length-percentage>var(--text-body)--cui-alert-description-gap<length-percentage>var(--spacing)--cui-alert-title-font-weight<number>var(--font-weight-medium)