Inkbox

Component

Badge

The pink BETA and ADMIN marks, the green Included pill, the pale webhook tags, and the tunnel's status wells.

npx -y github:anwarlemu/inkbox-brand-cli#release add badge
Preview
Agent2AgentBETAMy OrganisationADMINIncluded
Tags
EmailSignedFire-and-forgetBlacklistUnread
Status
ActiveIdleEdge
Variants
3 newDraftWebhookFailedArchivedDocs

Usage

Use pink for a feature or role marker beside a label (BETA, ADMIN), success size lg with a filled check-circle for something granted (Included), blue, purple and gray at size sm for event tags (Email, Signed, Fire-and-forget), green size sm for a rule mode (Blacklist), and size well for a status reading (Active on green, Idle on gray, Edge on blue). Default (purple) and destructive are for counts and errors.

Avoid

  • Caps typed with CSS
  • A badge as a button
  • More than three badges in a row
  • Saturated fills behind text

Exports: Badge, badgeVariants. Read the examples for composition and props.

Dependencies: radix-ui, class-variance-authority.

Example

examples/badge.tsx
import { CheckCircleIcon } from "@phosphor-icons/react/ssr";​import { Badge } from "@/components/ui/badge";​export function Preview() {  return (    <div className="flex flex-wrap items-center gap-3">      <span className="flex items-center gap-2.5 text-body text-fg">        Agent2Agent        <Badge variant="pink">BETA</Badge>      </span>      <span className="flex items-center gap-2.5 text-body text-fg">        My Organisation        <Badge variant="pink">ADMIN</Badge>      </span>      <Badge variant="success" size="lg">        <CheckCircleIcon weight="fill" />        Included      </Badge>    </div>  );}​export function Tags() {  return (    <div className="flex flex-wrap items-center gap-1.5">      <Badge variant="blue" size="sm">Email</Badge>      <Badge variant="purple" size="sm">Signed</Badge>      <Badge variant="gray" size="sm">Fire-and-forget</Badge>      <Badge variant="green" size="sm">Blacklist</Badge>      <Badge variant="blue" size="sm">Unread</Badge>    </div>  );}​export function Status() {  return (    <div className="flex flex-wrap items-center gap-6">      <Badge variant="green" size="well">Active</Badge>      <Badge variant="gray" size="well">Idle</Badge>      <Badge variant="blue" size="well">Edge</Badge>    </div>  );}​export function Variants() {  return (    <div className="flex flex-wrap items-center gap-2">      <Badge>3 new</Badge>      <Badge variant="secondary">Draft</Badge>      <Badge variant="outline">Webhook</Badge>      <Badge variant="destructive">Failed</Badge>      <Badge variant="ghost">Archived</Badge>      <Badge variant="link" asChild>        <a href="https://inkbox.ai/docs" target="_blank" rel="noreferrer">Docs</a>      </Badge>    </div>  );}

Source

components/ui/badge.tsx
import * as React from "react";import { Slot } from "radix-ui";import { cva, type VariantProps } from "class-variance-authority";​import { cn } from "@/lib/utils";​// Every badge in the console (Figma 427:2715). `pink` is BETA and ADMIN: a 1px pink edge, 4px corners, 12px pink text,// 22px tall with 6px sides. `success` is the Included pill: white with a 1px green edge, a filled check-circle (22px, the// design's 20px glyph at Phosphor's proportions) 4px in and a 14px green label, 28px tall. `blue`, `purple` and `gray` are the webhook tags (Email, Signed,// Fire-and-forget) at size sm: 11px medium on the pale fill, 4px corners, 17px tall; `green` is the Blacklist tag.// At size `well` they become the tunnel's 38px status wells (Active, Idle, Edge): 14px ink, 8px corners.const badgeVariants = cva(  "inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-xs border border-transparent font-sans whitespace-nowrap transition-[background-color,color] duration-150 ease-out focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring motion-reduce:transition-none [&>svg]:pointer-events-none [&>svg]:shrink-0",  {    variants: {      variant: {        default: "bg-primary text-on-primary [a&]:hover:bg-primary-hover",        secondary: "bg-subtle text-fg [a&]:hover:bg-subtle-hover",        destructive: "bg-danger text-white",        outline: "border-line-field bg-surface text-fg [a&]:hover:bg-subtle",        ghost: "text-fg-secondary [a&]:hover:bg-subtle",        link: "text-fg-brand underline-offset-4 [a&]:hover:underline",        pink: "rounded-sm border-pink bg-surface text-pink",        success: "rounded-pill border-success bg-surface text-success",        green: "bg-success-bg text-fg",        blue: "bg-tag-blue text-tag-blue-fg",        purple: "bg-tag-purple text-tag-purple-fg",        gray: "bg-tag-gray text-fg",      },      size: {        sm: "h-4.5 px-1 text-micro leading-tight font-medium [&>svg]:size-3.5",        default: "h-5.5 px-1.5 text-caption leading-tight [&>svg]:size-4",        lg: "h-7 gap-1.5 pr-2.5 pl-1 text-body leading-tight [&>svg]:size-5.5",        well: "h-9.5 rounded-control px-3.5 text-body leading-tight text-fg [&>svg]:size-5.5",      },    },    defaultVariants: { variant: "default", size: "default" },  },);​function Badge({ className, variant, size, asChild = false, ...props }: React.ComponentProps<"span"> & VariantProps<typeof badgeVariants> & { asChild?: boolean }) {  const Comp = asChild ? Slot.Root : "span";  return <Comp data-slot="badge" data-variant={variant ?? "default"} className={cn(badgeVariants({ variant, size }), className)} {...props} />;}​export { Badge, badgeVariants };

Reference: Figma 427:2715: the rail (BETA, ADMIN), Create Agent Identity (Included), Webhooks (Email, Signed, Fire-and-forget), iMessage (Blacklist), Tunnel (Active, Idle, Edge), Inbox (Unread).