Skip to content
Tier

Semantic badge

Pro

One 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.

Markdown
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

With the Candor CLI

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

TSX · The example above
"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>

PropTypeDefaultDescription
vocabularyrequiredstring—Which vocabulary the value is from: a built-in one (`severity`, `risk`, `effort`, `confidence`, `provenance`, `autonomy`, `classification`) or one given by `VocabulariesProvider`.
valuerequiredstring | 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.
renderuseRender.RenderProp | undefined—The element to draw instead of a `<span>`, with the badge's styles.
classNamestring | 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.

PropTypeDefaultDescription
vocabulariesrequiredVocabularies—The vocabularies to add, by name.
childrenReact.ReactNode | undefined—The part of the app that uses them.

Values

semanticVocabularies

The 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.

KeyEnglish
unknownUnknown
severity.criticalCritical
severity.seriousSerious
severity.warningWarning
severity.infoNote
risk.highHigh risk
risk.mediumMedium risk
risk.lowLow risk
effort.smallSmall effort
effort.mediumMedium effort
effort.largeLarge effort
confidence.highHigh confidence
confidence.mediumMedium confidence
confidence.lowLow confidence
confidence.unknownConfidence unknown
provenance.generatedAI-generated
provenance.modifiedAI-modified
provenance.noneNo AI used
provenance.unknownAI involvement not recorded
autonomy.R1Advise
autonomy.R2Draft
autonomy.R3Build & hold
autonomy.R4Ship with a window
autonomy.R5Full delegation
classification.publicPublic
classification.internalInternal
classification.confidentialConfidential
classification.restrictedRestricted

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>>