Kosmesis
Components

Badge

A small status/label pill. Purely presentational — no Morphos primitive to wrap.

Installation

npx kosmesis add badge
pnpm dlx kosmesis add badge
yarn dlx kosmesis add badge
bunx kosmesis add badge

Install the following dependencies:

npm install class-variance-authority
pnpm add class-variance-authority
yarn add class-variance-authority
bun add class-variance-authority

Copy and paste the following code into your project.

badge.tsx
import { cva, type VariantProps } from "class-variance-authority";import { StatelessComponent } from "@praxisjs/core";import { Component } from "@praxisjs/decorators";import type { Children } from "@praxisjs/shared";import { cn } from "@/lib/utils";export const badgeVariants = cva(  "inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 gap-1 [&_svg]:pointer-events-none [&_svg]:size-3",  {    variants: {      variant: {        default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",        secondary: "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",        destructive: "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90",        outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",      },    },    defaultVariants: {      variant: "default",    },  },);export interface BadgeProps extends VariantProps<typeof badgeVariants> {  as?: "span" | "a" | "div";  href?: string;  class?: string;  id?: string;  children?: Children;}@Component()export class Badge extends StatelessComponent<BadgeProps> {  render() {    const { as: Tag = "span", variant, class: cls, id, href, children } = this.props;    return (      <Tag id={id} href={Tag === "a" ? href : undefined} class={cn(badgeVariants({ variant }), cls)}>        {children}      </Tag>    );  }}

Install the following dependencies:

npm install @praxisjs/css
pnpm add @praxisjs/css
yarn add @praxisjs/css
bun add @praxisjs/css

Copy and paste the following code into your project.

badge.tsx
import { StatelessComponent } from "@praxisjs/core";import { cx, Stylesheet, Styled, tokenVars } from "@praxisjs/css";import { Component } from "@praxisjs/decorators";import type { Children } from "@praxisjs/shared";import { KosmesisTokens } from "@/lib/kosmesis-theme";const t = tokenVars(KosmesisTokens);class BadgeStyles extends Stylesheet {  $root = this.css({    display: "inline-flex",    alignItems: "center",    justifyContent: "center",    borderRadius: `calc(${t.radius} - 2px)`,    padding: "0.125rem 0.5rem",    fontSize: "0.75rem",    fontWeight: 500,    width: "fit-content",    whiteSpace: "nowrap",    flexShrink: 0,    gap: "0.25rem",  }).on("& svg", { pointerEvents: "none", width: "0.75rem", height: "0.75rem" });  $variantDefault = this.css({ border: "1px solid transparent", backgroundColor: t.primary, color: t.primaryForeground }).on(    "&:is(a):hover",    { backgroundColor: `color-mix(in oklab, ${t.primary} 90%, transparent)` },  );  $variantSecondary = this.css({    border: "1px solid transparent",    backgroundColor: t.secondary,    color: t.secondaryForeground,  }).on("&:is(a):hover", { backgroundColor: `color-mix(in oklab, ${t.secondary} 90%, transparent)` });  $variantDestructive = this.css({ border: "1px solid transparent", backgroundColor: t.destructive, color: "white" }).on(    "&:is(a):hover",    { backgroundColor: `color-mix(in oklab, ${t.destructive} 90%, transparent)` },  );  $variantOutline = this.css({ color: t.foreground }).on("&:is(a):hover", {    backgroundColor: t.accent,    color: t.accentForeground,  });}export type BadgeVariant = "default" | "secondary" | "destructive" | "outline";export interface BadgeProps {  variant?: BadgeVariant;  as?: "span" | "a" | "div";  href?: string;  class?: string;  id?: string;  children?: Children;}@Component()export class Badge extends StatelessComponent<BadgeProps> {  @Styled(BadgeStyles) $s!: BadgeStyles;  render() {    const { as: Tag = "span", variant = "default", class: cls, id, href, children } = this.props;    const variants: Record<BadgeVariant, string> = {      default: this.$s.$variantDefault,      secondary: this.$s.$variantSecondary,      destructive: this.$s.$variantDestructive,      outline: this.$s.$variantOutline,    };    return (      <Tag id={id} href={Tag === "a" ? href : undefined} class={cx(this.$s.$root, variants[variant], cls)}>        {children}      </Tag>    );  }}

Examples

About

Purely presentational — same as upstream shadcn/ui, since neither Morphos nor Radix has a badge primitive. Variants are backed by class-variance-authority.

Usage

import { Badge } from "@/components/ui/badge";

<Badge>Default</Badge>
<Badge variant="secondary">Secondary</Badge>
<Badge variant="destructive">Destructive</Badge>
<Badge variant="outline">Outline</Badge>
<Badge as="a" href="/status">Link badge</Badge>

Props

PropTypeDefault
variant"default" | "secondary" | "destructive" | "outline""default"
as"span" | "a" | "div""span"
hrefstring— (used when as="a")
classstring

On this page