Semantic badge
ProOne value from a vocabulary as a badge: an icon and a word, never a colour alone. Seven vocabularies are built in, their values those of the kit's own types, so a badge agrees with the item beside it: severity (as FindingData), risk, effort, confidence (as Confidence), provenance (as AiContentLabel's involvement), autonomy (R1 to R5, with ReviewLadder's names) and classification. Add your own with VocabulariesProvider.
A null value says "Unknown"; nothing is guessed. A value the vocabulary doesn't have is drawn as its own text, in an outline badge with no icon, and warns in development, so a typo or a new status shows rather than hides.
Version 5.2.0· other versions
This page is for 5.2.0, the current release. An earlier release’s page is the Markdown that release published, so the docs match the version you have installed (candor-lock.json records it).
Not in the docs of 1.3.0, 1.4.0, 1.5.0, 1.5.1, 1.6.0, 1.7.0, 1.8.0, 1.8.1, 1.9.0, 1.9.1, 2.0.0, 2.1.0, 2.2.0, 2.3.0, 2.4.0, 2.5.0, 2.5.1, 2.6.0, 2.6.1, 2.6.2, 2.7.0, 2.8.0, 2.9.0, 2.10.0, 3.0.0, 4.0.0, 4.0.1, 4.0.2 and 4.1.0: the page came later, or had another name then.
Docs pages weren’t kept for 1.0.0, 1.0.1, 1.1.0, 1.1.1, 1.2.0 and 1.2.1: they are kept from 1.3.0 on, and before that only llms.txt was published.
Preview
Loading the preview
Install
First time? Get started sets up the registry and theme. Or with shadcn directly: npx shadcn@latest add @candor/semantic-badge
Brings in: badge, bidi, locale, tokens, utils · npm: @base-ui/react@^1.9.0, lucide-react@^1.67.0
Usage
"use client"
import { CircleCheck, Hourglass, OctagonX } from "lucide-react"
import { SemanticBadge, VocabulariesProvider } from "@/components/candor/semantic-badge"
// Built-in vocabularies, an unknown value, and an app's own vocabulary through the provider.
export default function Example() {
return (
<VocabulariesProvider
vocabularies={{
delivery: {
waiting: { label: "Waiting on review", icon: Hourglass, tone: "warning" },
blocked: { label: "Blocked", icon: OctagonX, tone: "destructive" },
done: { label: "Done", icon: CircleCheck, tone: "success" },
},
}}
>
<div className="flex max-w-xl flex-wrap gap-2">
<SemanticBadge vocabulary="severity" value="serious" />
<SemanticBadge vocabulary="risk" value="medium" />
<SemanticBadge vocabulary="effort" value="small" />
<SemanticBadge vocabulary="confidence" value="low" />
<SemanticBadge vocabulary="provenance" value="generated" />
<SemanticBadge vocabulary="autonomy" value="R3" />
<SemanticBadge vocabulary="classification" value="confidential" />
<SemanticBadge vocabulary="risk" value={null} />
<SemanticBadge vocabulary="delivery" value="blocked" />
<SemanticBadge vocabulary="delivery" value="waiting" size="sm" />
</div>
</VocabulariesProvider>
)
}<SemanticBadge>
| Prop | Type | Default | Description |
|---|---|---|---|
| vocabularyrequired | string | — | Which vocabulary the value is from: a built-in one (`severity`, `risk`, `effort`, `confidence`, `provenance`, `autonomy`, `classification`) or one given by `VocabulariesProvider`. |
| valuerequired | string | null | — | The value. `null` when it isn't known, which the badge says as "Unknown". |
| size | "sm" | "default" | undefined | "default" | `sm` for dense rows and tables. |
| render | useRender.RenderProp | undefined | — | The element to draw instead of a `<span>`, with the badge's styles. |
| className | string | undefined | — | Classes for the badge, applied last. |
<VocabulariesProvider>
Adds an app's own vocabularies, and values to the built-in ones, for every SemanticBadge inside: a delivery status, a ticket priority. Each value is a word with an optional icon and tone. A built-in value's word can't be changed here (LocaleProvider's strings does that, under semanticBadge), so a severity reads the same everywhere. Nested providers add to the ones around them.
| Prop | Type | Default | Description |
|---|---|---|---|
| vocabulariesrequired | Vocabularies | — | The vocabularies to add, by name. |
| children | React.ReactNode | undefined | — | The part of the app that uses them. |
Values
semanticVocabulariesThe built-in vocabularies' icons and tones; their words are semanticBadgeStrings.
{
severity: {
critical: {
icon: LucideIcon;
tone: "destructive";
};
serious: {
icon: LucideIcon;
tone: "destructive";
};
warning: {
icon: LucideIcon;
tone: "warning";
};
info: {
icon: LucideIcon;
tone: "secondary";
};
};
risk: {
high: {
icon: LucideIcon;
tone: "destructive";
};
medium: {
icon: LucideIcon;
tone: "warning";
};
low: {
icon: LucideIcon;
tone: "secondary";
};
};
effort: {
small: {
icon: LucideIcon;
tone: "secondary";
};
medium: {
icon: LucideIcon;
tone: "secondary";
};
large: {
icon: LucideIcon;
tone: "secondary";
};
};
confidence: {
high: {
icon: LucideIcon;
tone: "success";
};
medium: {
icon: LucideIcon;
tone: "secondary";
};
low: {
icon: LucideIcon;
tone: "warning";
};
unknown: {
icon: LucideIcon;
tone: "outline";
};
};
provenance: {
generated: {
icon: LucideIcon;
tone: "accent";
};
modified: {
icon: LucideIcon;
tone: "accent";
};
none: {
icon: LucideIcon;
tone: "secondary";
};
unknown: {
icon: LucideIcon;
tone: "outline";
};
};
autonomy: {
R1: {
icon: LucideIcon;
tone: "secondary";
};
R2: {
icon: LucideIcon;
tone: "secondary";
};
R3: {
icon: LucideIcon;
tone: "secondary";
};
R4: {
icon: LucideIcon;
tone: "accent";
};
R5: {
icon: LucideIcon;
tone: "attention";
};
};
classification: {
public: {
icon: LucideIcon;
tone: "secondary";
};
internal: {
icon: LucideIcon;
tone: "secondary";
};
confidential: {
icon: LucideIcon;
tone: "warning";
};
restricted: {
icon: LucideIcon;
tone: "destructive";
};
};
}Strings
The fixed words, in English by default. Change any of them under semanticBadge in <LocaleProvider strings={{ … }}>; the table is exported as semanticBadgeStrings.
| Key | English |
|---|---|
| unknown | Unknown |
| severity.critical | Critical |
| severity.serious | Serious |
| severity.warning | Warning |
| severity.info | Note |
| risk.high | High risk |
| risk.medium | Medium risk |
| risk.low | Low risk |
| effort.small | Small effort |
| effort.medium | Medium effort |
| effort.large | Large effort |
| confidence.high | High confidence |
| confidence.medium | Medium confidence |
| confidence.low | Low confidence |
| confidence.unknown | Confidence unknown |
| provenance.generated | AI-generated |
| provenance.modified | AI-modified |
| provenance.none | No AI used |
| provenance.unknown | AI involvement not recorded |
| autonomy.R1 | Advise |
| autonomy.R2 | Draft |
| autonomy.R3 | Build & hold |
| autonomy.R4 | Ship with a window |
| autonomy.R5 | Full delegation |
| classification.public | Public |
| classification.internal | Internal |
| classification.confidential | Confidential |
| classification.restricted | Restricted |
Types
- SemanticTone
- A badge's tone: one of `Badge`'s variants. The tone is never the meaning on its own; every value has a word.
"default" | "secondary" | "outline" | "accent" | "success" | "warning" | "destructive" | "attention" | "running"- VocabularyValue
- One value of a vocabulary: its word, and the icon and tone it is drawn with.
{ /** The value's word, as the app names it: "Blocked". */ label: string; /** The icon drawn before the word. Left out, the word stands alone. */ icon?: LucideIcon | undefined; /** The badge's tone. Default `secondary`. */ tone?: SemanticTone | undefined; }- Vocabularies
- An app's own vocabularies, by name, each a record of its values: `{ delivery: { blocked: { label: "Blocked", … } } }`.
Record<string, Record<string, VocabularyValue>>