Folio

Components

Badge & Tag

One component, two jobs. Badge is a colored status pill -- counts, states, severity. Tag (a wrapper over Badge with a fixed neutral look) is a label / category / keyword, and the only one that can be removable.

Preview

Active
Engineering

Every color maps to a Folio feedback token -- no raw Tailwind palette utilities.

Status (Badge)

Default
<Badge>Default</Badge>
Success
<Badge color="success">Success</Badge>
Destructive
<Badge color="destructive">Destructive</Badge>
Warning
<Badge color="warning">Warning</Badge>
Info
<Badge color="info">Info</Badge>

Semantic intent is the color prop, combined with variant (solid / soft / outline). The error value is destructive.

Label (Tag)

Engineering
Design
<Tag>Engineering</Tag>
Neutral label
<Badge variant="outline" className="bg-secondary">
  Neutral label
</Badge>

A Tag is just an outline Badge on the secondary surface -- neutral, no color axis. Use it for taxonomy, not state.

Removable (filter chips)

React
TypeScript
Design Systems
Accessibility

removable lives on Tag only -- it renders a ✕ button and fires onRemove. This is the canonical filter-chip pattern. Badges are never removable (status isn't dismissable).

API

Badge
Prop
Type
Default
Description
variant
"default" | "secondary" | "outline"
"default"
Fill style -- solid, tonal, or bordered.
color
"default" | "primary" | "destructive" | "success" | "warning" | "info" | "orange" | "amber" | "lime" | "emerald" | "teal" | "cyan" | "sky" | "fuchsia" | "pink" | "rose"
"default"
Semantic color. Folio has no raw palette, so each hue color uses the closest status token.
size
"default" | "sm"
"default"
Standard or compact.
asChild
boolean
false
Render the child element as the badge.
Tag (wrapper over Badge)
Prop
Type
Default
Description
removable
boolean
false
Render a trailing ✕ button (interactive chip).
onRemove
() => void
—
Fired when the ✕ is clicked.
size
"default" | "sm"
"default"
Standard or compact.
asChild
boolean
false
Render the child element as the tag (non-removable only).

Don't and Do

Don't

Don't color a category (that's a neutral Tag), and don't make a status removable (status isn't dismissable). Never fake either with a pill-shaped Button.

Do
// Status = colored Badge; label/category = Tag
<Badge color="success">Active</Badge>
<Tag>Engineering</Tag>
import { Badge } from "@/components/shadcn/badge";
import { Tag } from "@/components/folio/tag";

// Live status (color/count/state)
<Badge color="success">Active</Badge>

// Neutral label / category / keyword
<Tag>Engineering</Tag>

// Removable filter chip
<Tag removable onRemove={() => remove("react")}>React</Tag>
One implementation: Badge from @distylai/toolkit-ui; Tag is the neutral wrapper that adds removable. Colors are Folio tokens.