import { ApprovalCard } from "@elabs-ai/components-ai";npm install @elabs-ai/components-tokens @elabs-ai/components-ui @elabs-ai/components-aiPrompt for your coding agent
Paste it into Claude Code, Cursor, Codex or any other coding agent. Text in [brackets] is yours to fill in.
Add the brand-ui ApprovalCard component (from @elabs-ai/components-ai) to this project. 1. Read https://elabs-ai.com/llms.txt first: it maps every package and the rules. If you can use MCP servers, connect https://elabs-ai.com/mcp and use its search, docs and tokens tools. If not, run the same lookups in the terminal: `npx -y @elabs-ai/components-cli search "<what you need>"` and `npx -y @elabs-ai/components-cli docs <Component>`. 2. Look ApprovalCard up before writing code: `npx -y @elabs-ai/components-cli docs ApprovalCard` prints its real props, variants, what it pairs with and what to avoid. 3. If @elabs-ai/components-ai is not installed yet: `pnpm add @elabs-ai/components-tokens @elabs-ai/components-ui @elabs-ai/components-ai` (or `npm install @elabs-ai/components-tokens @elabs-ai/components-ui @elabs-ai/components-ai`). If this is the first brand-ui package in the project, wire it once: import `@elabs-ai/components-tokens/styles.css` plus the `themes/light.css` and `themes/dark.css` stylesheets in the CSS entry, add one Tailwind `@source` line per installed @elabs-ai package (Tailwind does not scan node_modules, so without it everything renders unstyled), and wrap the app root in `ThemeProvider` from `@elabs-ai/components-tokens`. 4. Use it here: [the screen or file, and what it should show] 5. Rules: use only @elabs-ai/components-* components and the semantic tokens — no raw colours, no raw font sizes, no arbitrary Tailwind values. Look up each component's real props with the docs tool before you use it; never guess a prop. 6. Done means: the typecheck passes, `npx -y @elabs-ai/components-cli audit src --strict` reports nothing, and you have opened the app and looked at every screen you touched in the light and the dark theme.
Avoid
- Reaching for it in a console transcript — the console skin is TerminalPermission, which reads the same promoted ApprovalScope model.
- Building a second approve/deny widget — ApprovalCard and Confirmation ship from the same module; extend, don't fork.
- Running the action the card describes on render — the card emits a decision; the app performs it (D5).
- Leaving the request mounted after the human answers — swap to ApprovalCardAccepted/ApprovalCardRejected so the outcome stays legible.
- Hand-rolling roving focus across the options — the option list is a real Radix RadioGroup; arrow-key wrap is the primitive's job.
- Offering 'always' and 'once' with the same words — the scope sentence is what stops a session-wide grant from reading like a single yes.
- Making the deny reason a separate step — the reason field writes into the card's own state and rides along with whichever choice is committed.
Works with
Contains
Pairs with
Examples
Approved
Denied
Scoped Options
Scoped Options Deny With Reason
API
ApprovalCard
| Prop | Type | Description |
|---|---|---|
approval | ToolUIPartApproval | |
staterequired | ToolUIPart["state"] |
ApprovalCardAccepted
| Prop | Type | Description |
|---|---|---|
children | ReactNode |
ApprovalCardAction
ApprovalCardActions
ApprovalCardApprove
ApprovalCardDeny
ApprovalCardDescription
ApprovalCardOptions
| Prop | Type | Description |
|---|---|---|
optionsrequired | ApprovalOption[] | |
value | string | |
defaultValue | string | |
onValueChange | (id: string) => void | |
onConfirm | (option: ApprovalOption, reason?: string) => void | Fires when an option is selected — by click, or by ANY keyboard move within the radio group (Home/End/arrow keys select immediately, per the native/ARIA radiogroup pattern Radix implements; there is no separate "highlight vs commit" step). Reports the full resolved `ApprovalOption` plus whatever reason text is currently held by a sibling `ApprovalCardReason` — type a reason BEFORE choosing an option to have it included in this call. |
ApprovalCardReason
ApprovalCardRejected
| Prop | Type | Description |
|---|---|---|
children | ReactNode |
ApprovalCardRequest
| Prop | Type | Description |
|---|---|---|
children | ReactNode |
ApprovalCardTarget
ApprovalCardTitle
Theming
The tokens each state resolves to. Change the token and every theme follows.
| State | Token |
|---|---|
| scope | each option's blast radius (once / session / always / deny) is a SENTENCE linked by aria-describedby, never a colour |
| pending | role=group + aria-labelledby while the human decides — the card holds focusable controls, so it is not a live region |