Usage
Callout draws attention to information that matters in context—an integration running degraded, a read-only workflow, a regional success—without pulling users out of what they're doing. It lives inline in the page, scoped to the section it qualifies, rather than hovering over everything like a Modal or flashing through a Snackbar. Built on Radix Themes, Callout supports five semantic variants, an optional description, a primary CTA, a secondary icon action, and dismissal.
No CAD connection
No CAD incident has been linked to this call
When deciding whether a piece of information belongs in a callout, a modal, a snackbar, or a message, ask where the user needs the information and how long it has to stay there. Callout earns its weight when context matters more than interruption.
Use Callout to surface conditions that change how a user should interpret what they're looking at: a CAD integration returning stale data, a read-only workflow, a degraded service that makes the rest of the page less trustworthy. The callout stays in place until the condition resolves, giving the user persistent context without blocking their work.
When an inline action completes in a specific part of the page, place a Success or Error callout immediately adjacent to the affected fields. The callout scopes the feedback to the right place—the user doesn't have to guess which form or table the confirmation refers to.
For warnings that need to be seen but don't require a blocking confirmation, a dismissible Callout gives the user a persistent acknowledgment without breaking their flow. Reserve this pattern for conditions the user can safely ignore for the current session.
Reach for Snackbar when feedback should vanish on its own after a few seconds. Save-succeeded confirmations, background-sync notifications, and other disposable outcomes belong there, not in a persistent callout.
Actions that destroy data, abandon workflows, or otherwise demand intentional friction belong in a Modal. Callout is inherently dismissible or ignorable; use a dialog when the user must deliberately confirm.
Chat-style content with multiple speakers, ongoing turns, or threaded responses belongs in Message, not stacked callouts. A callout represents a single moment of context; a message thread represents a conversation.
CalloutType has five variants, each tuned to a specific intent. Use the lightest variant that still communicates the right urgency—reserving the strong variants for the conditions that earn them is what keeps the console readable.
Note is the neutral baseline. Use it for background context, policy reminders, or configuration notes that aren't tied to severity. It carries no alarm signal; it simply informs.
Info marks context the user needs in order to interpret what they're seeing. An info callout might explain why a normally-available action is hidden, or point out that the currently-displayed data is filtered. It signals "read this before acting."
Success confirms that a positive condition holds—a sync completed, a resource came online, an override took effect. Reserve it for confirmations the user will want to verify later; for transient success, use Snackbar instead.
Warning signals a condition that needs attention but isn't failing. Throttled integrations, deprecated workflows, and capacity limits approaching a threshold all fit here. It asks for acknowledgment without implying a break.
Error is the strongest variant and the most easily abused. Use it only for conditions that require remediation: a failed integration, a validation blocker, a service outage. Do not reach for error styling to add marketing emphasis to a neutral message.
A Callout is a single row with predictable structure: a variant icon, a title, an optional description, and an optional actions cluster on the trailing edge. The sections below walk through each slot and what belongs in it.
The icon is derived from the variant and should not be overridden. It acts as the first visual signal of severity; swapping it for a decorative icon undermines the semantic meaning that callout types are there to provide. When isLoading is set, the icon is replaced with a loading indicator in-place, preserving the row's geometry.
The title is the core message and the only required piece of copy. Write it as an action-oriented statement rather than a label—"Integration degraded" rather than "Integration status." Titles wrap when they must, but tight phrasing is better than a multi-line header. Pass title from formatMessage or formatInternalMessage as a LocalizedMessage; raw string literals do not typecheck.
The description sits below the title and carries the specifics: what is degraded, which region is affected, how long until the next check. Reserve it for information that adds value beyond the title; an empty or tautological description just widens the component without helping. Descriptions accept localized strings, CoreText, text-only FlexBox compositions, or semantic lists inside Typography. Use FlexBox with CoreText for stacked facts such as CFS details and reserve Typography for content that is semantically a ul or ol. Route CTAs to ctaButton / secondaryIconButton; route forms and multi-control layouts to Card.
CalloutType owns title and description text color. Nested CoreText, Typography, list item text, and ::marker bullets inherit the variant's semantic color automatically. Do not pass CoreText.color or custom classes to override callout copy color.
Do not embed in description:
Card or Card-sized interactive layoutsctaButton should carry the primary actionUse Card for instruction panels and inline forms. See COMPOSITION.md in @prepared911/ui-core for the full agent-facing contract.
The ctaButton is the primary action. It should be a single strong verb tied to resolving or investigating the callout's condition: "View status," "Retry sync," "Open settings." If the natural action is destructive or irreversible, route the user through a Modal instead—a callout CTA is not a confirmation surface.
The secondaryIconButton sits to the left of the CTA and holds a related but non-primary action—typically a link out, a refresh, or a help pointer. Use it sparingly; every added action in the row taxes the user's attention.
The dismissible control is flush right. It's appropriate when the user can safely suppress the message for the current session; it is not appropriate for conditions the user must see until resolved. A callout that should stay put is one without a dismiss.
The action cluster is driven by three independent props, composed in this order: secondaryIconButton, then ctaButton, then dismiss. Any combination is valid, but restraint reads better than a crowded row.
A callout CTA should name the outcome, not the mechanism: "View incidents" rather than "Click here," "Resume sync" rather than "Try again." Match the verb to the variant—warning and error callouts typically ask for remediation, success callouts for verification, info callouts for exploration.
Use secondaryIconButton when a related context link or quick utility belongs next to the primary action—opening a status page alongside a "Retry" CTA, for example. If the secondary action has equal weight to the primary, consider escalating the condition to a Modal where two buttons are a natural pairing.
If the natural CTA for a callout would delete data, archive a record, or abandon an in-progress workflow, do not put it in the callout. Use the callout to explain the condition, then link to a Modal where the destructive confirmation can be treated with the friction it deserves.
Titles should be concise and action-oriented. Descriptions should add specifics the title omits rather than rephrasing it. Run all user-visible strings through formatMessage so translations stay consistent with the rest of the console.
Avoid stacking callouts in a single viewport. A region with three simultaneous callouts is usually one that needs to consolidate or escalate—pick the most important condition, link to the others if they still matter, and let the page breathe.
Errors belong adjacent to what they explain. A failed-save callout above a form is useful; the same callout at the top of the page, buried beneath the header, is not.
Callout derives a semantic role from its variant: Note and Info render as role="note", Success and Warning as role="status", and Error as role="alert". Override the role through the role prop only when the default doesn't match the condition—a success callout that represents a blocking confirmation, for instance. The variant icon supplements the text rather than replacing it; screen readers announce the title and description via the callout's ARIA label, which defaults to a localized variant name and can be overridden with ariaLabel.
Snackbar for transient, auto-dismissing feedback.Modal for blocking confirmations.Message for conversational or threaded content.Page header for page-level warnings beside titles.On this page