Skip to content
Sign in
SafetyWhy cardMenu

Why cardPro

Why the agent did that: the instruction, the evidence and the rule, a click from the action.

ProTwo actions from a reply, each with its reasons a click away.

Installation

$ pnpm dlx shadcn@latest add @chatcn-pro/why-card

Usage

tsx
import { WhyCard } from "@/components/ui/chatcn/pro/why-card"

<WhyCard
  action="Drafted the reply and left it unsent."
  instruction={{ text: "Check with me before anything goes out.", source: "You, Monday 09:12" }}
  evidence={[{ label: "Email from Halden Lettings", source: "Mail" }]}
  rule={{ text: "Ask before emailing outside your contacts.", id: "mail.send.external" }}
/>

The reasons read as a chain that ends in the action: you asked, it found, the rule says, so it did this. Each step has its own mark on the rail (a tick, a ring, a square, a solid dot for the conclusion), so the steps stay distinct in grayscale. Missing steps say so plainly instead of disappearing. Use inline where the reasons should push content down and stay open.

Examples

States

ProInline and open, small, loading, nothing recorded and long content.

Props

PropTypeNotes
actionReactNodeWhat the agent did, the end of the chain
instruction{ text, source? }The person's words, quoted
evidence{ label, detail?, source?, href? }[]What it looked at
rule{ text, source?, id? }The rule that applied; id shows in mono
variant"popover" | "inline"Default popover
size"sm" | "md"Trigger size. Default md
loadingbooleanReasons are still being read from the trace
open, defaultOpen, onOpenChangeControlled or uncontrolled
traceHrefstringAdds an Open the trace link
label, labelsstring, Partial<WhyLabels>Trigger and step titles, for translation

Keyboard

KeyAction
Enter or SpaceOpen or close the reasons
EscClose the popover and return focus to the trigger

Accessibility

  • The trigger names what it explains; the count of reasons is hidden from screen readers.
  • The chain is an ordered list, so steps are announced in order.
  • The inline variant uses aria-expanded and aria-controls on the trigger.

Motion

The popover grows from the trigger in 180 ms. The inline panel slides 4 px and fades in 180 ms. Opened from the keyboard, nothing animates. Reduced motion keeps the fade only.