Badge
interlace-ui/badgeFreeComponent
A small pill for a status, a count, a label or a tag. Renders a `<span>` by default, or whatever Base UI's `render` prop is given, so the same badge can be an anchor without losing its shape.
Install it
npx shadcn@latest add https://ds.interlace.tools/r/badge.jsonSource
1import * as React from 'react';23// @interlace/badge v1.3.0 — Interlace design system.4// Docs, props and live preview: https://ds.interlace.tools/c/badge5// What changed since: https://ds.interlace.tools/c/badge#history6// Generated banner — keep it, the upgrade diff reads this version.78/**9 * @interlace/ui — Badge10 *11 * A small pill for a status, a count, a label or a tag. Renders a `<span>` by12 * default, or whatever Base UI's `render` prop is given, so the same badge can13 * be an anchor without losing its shape.14 *15 * Six variants, and every one that names a text colour also paints an opaque16 * surface under it — see the rule below.17 *18 * ## Anatomy19 *20 * Badge (span by default, or the `render` element)21 * └─ children (text and/or an svg, sized to size-3 here)22 *23 * ## The variant rule this file exists to hold24 *25 * A badge is dropped onto surfaces the design system does not control. So a26 * variant that declares a foreground must paint an opaque background in the27 * same state, and a variant with no surface of its own (`ghost`, `link`) must28 * inherit its colour rather than name one. The per-variant comments below29 * record the measured failures that produced that rule — `link` with30 * `text-primary` measured 1.00:1 inside a `bg-primary` section — and31 * `composite-contrast-lock` is what keeps it true.32 *33 * ## `loading` and the hook order34 *35 * Until 2026-08-11 `useRender` sat AFTER the `loading` early return, so the36 * hook was behind a conditional. Toggling `loading` on a mounted Badge did not37 * actually throw — Base UI's `useRenderElement` occupies one hook slot on every38 * path — but the ordering was invalid regardless of whether this version of39 * that dependency happened to tolerate it. `useRender` is now unconditional and40 * its result discarded on a loading render.41 *42 * ## Why there is no `'use client'` here43 *44 * There used to be one, and the R25 row below used to read "Required —45 * `useRender` is a hook". That reasoning was wrong: `useRender` is a hook, but46 * a hook is only a client boundary if it needs client state, and this one does47 * not. `@base-ui/react/use-render` ships no `'use client'` of its own, and48 * `useRenderElement` guards its single hook (`useMergedRefs`) behind49 * `typeof document !== 'undefined'` — on the server it takes the no-hook path50 * and just builds an element. Which is exactly why `Stack`, `Container`,51// … truncated
More from interlace-ui
All 140 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| A11y Startera11y-starter | interlace-ui | Components | Free | no deps | |
| Accordionaccordion | interlace-ui | Components | Free | no deps | |
| Alertalert | interlace-ui | Components | Free | no deps | |
| Alert Dialogalert-dialog | interlace-ui | Components | Free | no deps | |
| Animated Gradient Textanimated-gradient-text | interlace-ui | Components | Free | no deps | |
| Animated Grid Patternanimated-grid-pattern | interlace-ui | Components | Free | no deps | |
| Animated Listanimated-list | interlace-ui | Components | Free | no deps | |
| Article Cardarticle-card | interlace-ui | Components | Free | no deps |
