Components
Badge
Small chip for a status, brand or accent label, or a user-defined tag in one of nine hues.
PreviewOpen ↗
Code
import { Badge } from "@fadymondy/nasaq/web";export function IssueState() { return <Badge variant="warning">قيد المراجعة</Badge>;}Data Display · stable
Live examples and controls: Badge in the lab.
Install
npx shadcn@latest add https://docs.nasaqui.com/r/badge.jsonA 20px high chip (h-5, 4px radius, caption text) rendered as a <span>. Its variant sets the colour role.
Statuses use fixed hues shared by every brand. brand and accent are identity, not status. tag is for
user-defined categories, with a hue chosen from nine.
When to use
- A status that needs its own chip:
success,warning,danger,info. - A short count or label: "Pro" (
brand), "New" (accent), a delta (outline). - User-defined labels or categories:
variant="tag"with ahue.
When not to use
- An inline status in a table cell, list row or header, where a chip is too heavy: use
Status. Its icon shape differs per tone, so it reads without colour. - A status carried by colour alone: every badge needs a label. Prefer an icon as well.
- Tags used as status: the
taghues are categories, never state. - A clickable control: a badge is not interactive. Use
Button.
Import
import { Badge, badgeVariants, TAG_HUES, type BadgeProps, type TagHue } from "@fadymondy/nasaq/web";
// inside this monorepo: "@nasaq/web"Quick start
import { Badge } from "@fadymondy/nasaq/web";
export function IssueState() {
return <Badge variant="warning">قيد المراجعة</Badge>;
}Anatomy
Badge data-slot="badge" <span>, optional leading svg (12px) then textAPI
Badge
BadgeProps extends ComponentProps<"span">, VariantProps<typeof badgeVariants>.
| Prop | Type | Default | Description |
|---|---|---|---|
variant? | "neutral" | "outline" | "brand" | "accent" | "success" | "warning" | "danger" | "info" | "tag" | "neutral" | Colour role (table below). |
hue? | TagHue | "gray" | Tag colour. Only used when variant="tag"; sets --tag-solid and --tag-soft from --nq-tag-<hue> and --nq-tag-<hue>-soft. |
className? | string | none | Merged after the variant classes. |
style? | CSSProperties | none | Merged after the tag custom properties. |
...props | ComponentProps<"span"> | none | Forwarded to the <span>. |
Variants (badgeVariants):
| Variant | Meaning | Classes |
|---|---|---|
neutral | Default, generic | border-border bg-secondary text-foreground |
outline | Quiet, counts and deltas | border-border text-muted-foreground |
brand | Product identity ("Pro", the tenant's brand). Not a status. | brand border at 40%, brand 14% fill, text-foreground |
accent | Nasaq gold: featured, new. Not a status. | border-nq-accent/40 bg-nq-accent/15 text-nq-accent-text |
success | Done, healthy, paid, live | border-nq-success/40 bg-nq-success-soft text-nq-success-text |
warning | Needs attention, at risk, expiring | border-nq-warning/40 bg-nq-warning-soft text-nq-warning-text |
danger | Failed, overdue, error, revoked | border-nq-danger/40 bg-nq-danger-soft text-nq-danger-text |
info | Running, syncing, scheduled | border-nq-info/40 bg-nq-info-soft text-nq-info-text |
tag | User-defined category | border-transparent bg-[var(--tag-soft)] text-[var(--tag-solid)] |
Other exports
| Export | Type | Description |
|---|---|---|
TAG_HUES | readonly ["gray","red","orange","amber","green","teal","blue","violet","pink"] | The nine tag hues, in order. |
TagHue | "gray" | "red" | "orange" | "amber" | "green" | "teal" | "blue" | "violet" | "pink" | Type of hue. |
badgeVariants | cva(...) | Class generator: badgeVariants({ variant }). Use it to give another element badge styling. |
BadgeProps | interface | Props of Badge. |
Examples
Statuses, with an icon
import { Badge } from "@fadymondy/nasaq/web";
import { CircleCheck, CircleX } from "lucide-react";
export function Results() {
return (
<div className="flex gap-2">
<Badge variant="success">
<CircleCheck aria-hidden />
مكتملة
</Badge>
<Badge variant="danger">
<CircleX aria-hidden />
متوقفة
</Badge>
</div>
);
}User tags
import { Badge, type TagHue } from "@fadymondy/nasaq/web";
export function Tags({ tags }: { tags: { name: string; hue: TagHue }[] }) {
return (
<div className="flex flex-wrap gap-1.5">
{tags.map((t) => (
<Badge key={t.name} variant="tag" hue={t.hue}>
{t.name}
</Badge>
))}
</div>
);
}Every tag hue
import { Badge, TAG_HUES } from "@fadymondy/nasaq/web";
export function AllHues() {
return (
<div className="flex flex-wrap gap-2">
{TAG_HUES.map((hue) => (
<Badge key={hue} variant="tag" hue={hue}>
{hue}
</Badge>
))}
</div>
);
}Delta with an LTR figure
import { Badge } from "@fadymondy/nasaq/web";
import { TrendingUp } from "lucide-react";
export function Delta() {
return (
<Badge variant="outline">
<TrendingUp />
<span dir="ltr">+12.4%</span>
</Badge>
);
}Badge styling on another element
import { badgeVariants } from "@fadymondy/nasaq/web";
export function BadgeLink() {
return (
<a href="/pro" className={badgeVariants({ variant: "brand" })}>
Pro
</a>
);
}Accessibility
A badge is a static <span> with no role. It is not focusable.
- The label is the meaning. Never rely on hue alone; pair status with text and, where possible, an icon.
- Mark decorative icons inside a badge with
aria-hidden. - For a bare count with no visible unit ("3"), put an accessible name nearby or use
aria-label. - Localise the text yourself.
RTL & i18n
- The badge is
inline-flexwithgap-1, so an icon before the text followsdir. - Directional icons (arrows, chevrons) need mirroring in RTL. Trend and status icons do not.
- Keep numbers, percentages and signs LTR inside Arabic text:
<span dir="ltr">+12.4%</span>orNumfrom the numeric component. - No built-in strings.
Styling & tokens
- Status tokens:
--nq-{success,warning,danger,info}with-softand-text. Identity:--nq-brand,--nq-accent. Tags:--nq-tag-<hue>and--nq-tag-<hue>-soft. - The status hues are fixed across brands. Do not remap them.
- Target with
[data-slot=badge]. Extend withclassName; never override colours with raw hex.
Do / Don't
- Do use
success/warning/danger/infofor state, and always include a label. - Do use
brandfor product identity andaccentfor featured/new, never as a status. - Do use
Statusinstead of a badge inside dense table cells and lists. - Don't use
taghues to mean state. - Don't invent a variant with raw hex; use the tokens.
- Don't make a badge clickable.
Related
Lab
https://docs.nasaqui.com/?path=/docs/components-data-display-badge--docs