Callout
Styled message block with info, warning, success, and error variants. Supports data-driven rules, embedded metrics, collapsible detail, action buttons, and auto-dismiss.
import { Callout } from "metricui";Use Callout to surface contextual messages, alerts, and status notifications inside dashboards. It supports four semantic variants, data-driven rules that auto-select variant and message based on a numeric value, embedded formatted metrics, collapsible detail sections, action buttons, and auto-dismiss timers.
Basic Example
Heads up
<Callout variant="info" title="Heads up">
This is an informational message for the user.
</Callout>All Variants
Four semantic variants cover the most common dashboard alert scenarios. Each has a distinct icon, border color, and background tint.
Info
Warning
Success
Error
<Callout variant="info" title="Info">...</Callout>
<Callout variant="warning" title="Warning">...</Callout>
<Callout variant="success" title="Success">...</Callout>
<Callout variant="error" title="Error">...</Callout>Data-Driven Rules
Pass a value and rules array to let the Callout auto-select its variant and message. Rules are evaluated top-to-bottom; first match wins. Use {value} in title or message for interpolation.
Performance good
<Callout
value={85}
rules={[
{ min: 90, variant: "success", title: "Excellent", message: "Score: {value}." },
{ min: 70, max: 90, variant: "info", title: "Good", message: "Score: {value}." },
{ min: 50, max: 70, variant: "warning", title: "Degraded", message: "Score: {value}." },
{ max: 50, variant: "error", title: "Critical", message: "Score: {value}." },
]}
/>Metric Callout
The metric prop embeds a formatted numeric value inside the callout, using the same format engine as KpiCard (currency, percent, compact, etc.).
Revenue milestone reached
<Callout
variant="success"
title="Revenue milestone reached"
metric={{ value: 1000000, format: "currency", label: "total revenue" }}
>
Your team crossed the $1M revenue mark this quarter.
</Callout>Collapsible Detail
Use detail to tuck verbose information behind a toggle. Great for error stack traces, service breakdowns, or audit logs.
3 services experiencing elevated latency
<Callout
variant="warning"
title="3 services experiencing elevated latency"
detail={
<div className="space-y-1">
<p>API Gateway: p99 latency 450ms (threshold: 200ms)</p>
<p>Auth Service: p99 latency 320ms (threshold: 150ms)</p>
<p>Search: p99 latency 280ms (threshold: 100ms)</p>
</div>
}
>
Some services are responding slower than expected.
</Callout>Action Button
The action prop adds a button to the callout for inline user actions like retrying a failed operation or navigating to a detail view.
Payment failed
<Callout
variant="error"
title="Payment failed"
action={{ label: "Retry payment", onClick: () => alert("Retrying...") }}
>
The last payment attempt was declined.
</Callout>Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | CalloutVariant | "info" | Visual variant: "info", "warning", "success", or "error". Ignored when rules is used. |
title | string | — | Title text. |
children | React.ReactNode | — | Body content. |
icon | React.ReactNode | null | — | Icon override. Default: auto-picked per variant. Set to null to hide. |
value | number | null | — | Value to evaluate against rules (data-driven mode). |
rules | CalloutRule[] | — | Rules evaluated top-to-bottom. First match wins. Supports {value} placeholder in title/message. |
metric | CalloutMetric | — | Embedded formatted metric value with label. |
dismissible | boolean | false | Show dismiss button. |
onDismiss | () => void | — | Callback when dismissed. |
autoDismiss | number | 0 | Auto-dismiss after N milliseconds. 0 = never. |
action | CalloutAction | — | Action button with label and onClick. |
detail | React.ReactNode | — | Collapsible detail content — hidden by default, toggle to show. |
detailOpen | boolean | false | Whether detail starts expanded. |
dense | boolean | false | Compact layout. Falls back to config.dense. |
className | string | — | Additional CSS class names. |
classNames | { root?: string; icon?: string; title?: string; body?: string; metric?: string; action?: string } | — | Sub-element class overrides. |
id | string | — | HTML id attribute. |
data-testid | string | — | Test id. |
drillDown | boolean | ((event: { value: number | null; variant: CalloutVariant }) => React.ReactNode) | — | Enable drill-down on callout click. `true` auto-generates a detail panel. Pass a render function for full control over the panel content. Requires DrillDown.Root wrapper. |
drillDownMode | DrillDownMode | "slide-over" | Presentation mode for the drill-down panel. "slide-over" (default) slides from the right, full height. "modal" renders centered and compact. |
Data Shape
interface CalloutRule {
min?: number; // Minimum value (inclusive). Omit for fallback.
max?: number; // Maximum value (exclusive). Omit for no upper bound.
variant: CalloutVariant; // Variant to apply.
title?: string; // Title text. Supports {value} placeholder.
message?: string; // Message text. Supports {value} placeholder.
icon?: React.ReactNode;
}
interface CalloutMetric {
value: number;
format?: FormatOption;
label?: string;
}
interface CalloutAction {
label: string;
onClick: () => void;
}
type CalloutVariant = "info" | "warning" | "success" | "error";Notes
- Uses forwardRef — you can pass a ref to the root element.
- Rules are evaluated top-to-bottom; first match wins. Use {value} placeholder in title/message for interpolation.
- The metric prop uses the format engine — pass any FormatOption (currency, percent, compact, etc.).
- Dismissible callouts fade out with a 200ms animation before removing from the DOM.
- autoDismiss sets a timer in milliseconds; useful for transient success messages.
- Has role='alert' for screen readers.
- In MetricGrid, Callout takes full width automatically (__gridHint = 'full').
- The
aiContextprop (inherited from BaseComponentProps) adds business context for AI Insights analysis. See the AI Insights guide for details.
Playground
Experiment with every prop interactively. Adjust the controls on the right to see the component update in real time.
Live Preview
Heads up
Code
<Callout
variant="info"
title="Heads up"
>
This is an example callout message.
</Callout>Props
Adjust props to see the callout update in real time
Visual variant (ignored when data-driven)