Kosmesis
Components

Stock Badge

A product stock-level badge. Purely presentational — no Morphos equivalent.

Installation

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

Copy and paste the following code into your project.

stock-badge.tsx
import { StatelessComponent } from "@praxisjs/core";import { Component } from "@praxisjs/decorators";import { cn } from "@/lib/utils";export type StockStatus = "in-stock" | "low-stock" | "out-of-stock";export interface StockBadgeProps {  status: StockStatus;  count?: number;  class?: string;}@Component()export class StockBadge extends StatelessComponent<StockBadgeProps> {  render() {    const { status, count, class: cls } = this.props;    const labels: Record<StockStatus, string> = {      "in-stock": "In stock",      "low-stock": count !== undefined ? `Only ${String(count)} left` : "Low stock",      "out-of-stock": "Out of stock",    };    return (      <span        data-status={status}        class={cn(          "inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-xs font-medium",          "data-[status=in-stock]:bg-emerald-500/10 data-[status=in-stock]:text-emerald-600 dark:data-[status=in-stock]:text-emerald-400",          "data-[status=low-stock]:bg-yellow-500/10 data-[status=low-stock]:text-yellow-600 dark:data-[status=low-stock]:text-yellow-400",          "data-[status=out-of-stock]:bg-muted data-[status=out-of-stock]:text-muted-foreground",          cls,        )}      >        <span class="size-1.5 rounded-full bg-current" />        {labels[status]}      </span>    );  }}

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.

stock-badge.tsx
import { StatelessComponent } from "@praxisjs/core";import { cx, Stylesheet, Styled, tokenVars } from "@praxisjs/css";import { Component } from "@praxisjs/decorators";import { KosmesisTokens } from "@/lib/kosmesis-theme";const t = tokenVars(KosmesisTokens);class StockBadgeStyles extends Stylesheet {  $badge = this.css({    display: "inline-flex",    alignItems: "center",    gap: "0.375rem",    borderRadius: "9999px",    padding: "0.125rem 0.5rem",    fontSize: "0.75rem",    fontWeight: 500,  })    .on('&[data-status="in-stock"]', { backgroundColor: "color-mix(in oklab, #10b981 10%, transparent)", color: "#10b981" })    .on('&[data-status="low-stock"]', { backgroundColor: "color-mix(in oklab, #eab308 10%, transparent)", color: "#a16207" })    .on('&[data-status="out-of-stock"]', { backgroundColor: t.muted, color: t.mutedForeground });  $dot = this.css({ height: "0.375rem", width: "0.375rem", borderRadius: "9999px", backgroundColor: "currentColor" });}export type StockStatus = "in-stock" | "low-stock" | "out-of-stock";export interface StockBadgeProps {  status: StockStatus;  count?: number;  class?: string;}@Component()export class StockBadge extends StatelessComponent<StockBadgeProps> {  @Styled(StockBadgeStyles) $s!: StockBadgeStyles;  render() {    const { status, count, class: cls } = this.props;    const labels: Record<StockStatus, string> = {      "in-stock": "In stock",      "low-stock": count !== undefined ? `Only ${String(count)} left` : "Low stock",      "out-of-stock": "Out of stock",    };    return (      <span data-status={status} class={cx(this.$s.$badge, cls)}>        <span class={this.$s.$dot} />        {labels[status]}      </span>    );  }}

Examples

About

Purely presentational — no Morphos equivalent. count only affects the label when status="low-stock" (renders "Only N left"); it's ignored for the other two statuses.

Usage

import { StockBadge } from "@/components/ui/stock-badge";

<StockBadge status="low-stock" count={3} />

Props

PropTypeDefault
status"in-stock" | "low-stock" | "out-of-stock"
countnumber
classstring

On this page