Components
Payment Status
A payment-state badge with a colored dot. Purely presentational — no Morphos equivalent.
Installation
npx kosmesis add payment-statuspnpm dlx kosmesis add payment-statusyarn dlx kosmesis add payment-statusbunx kosmesis add payment-statusCopy and paste the following code into your project.
import { StatelessComponent } from "@praxisjs/core";import { Component } from "@praxisjs/decorators";import { cn } from "@/lib/utils";export type PaymentStatusValue = "succeeded" | "processing" | "failed" | "refunded";export interface PaymentStatusProps { status: PaymentStatusValue; class?: string;}const LABELS: Record<PaymentStatusValue, string> = { succeeded: "Succeeded", processing: "Processing", failed: "Failed", refunded: "Refunded",};@Component()export class PaymentStatus extends StatelessComponent<PaymentStatusProps> { render() { const { status, class: cls } = this.props; return ( <span data-status={status} class={cn( "inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium", "data-[status=succeeded]:bg-emerald-500/10 data-[status=succeeded]:text-emerald-600 dark:data-[status=succeeded]:text-emerald-400", "data-[status=processing]:bg-muted data-[status=processing]:text-muted-foreground", "data-[status=failed]:bg-destructive/10 data-[status=failed]:text-destructive", "data-[status=refunded]:bg-secondary data-[status=refunded]:text-secondary-foreground", cls, )} > <span class="size-1.5 rounded-full bg-current" /> {LABELS[status]} </span> ); }}Install the following dependencies:
npm install @praxisjs/csspnpm add @praxisjs/cssyarn add @praxisjs/cssbun add @praxisjs/cssCopy and paste the following code into your project.
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 PaymentStatusStyles extends Stylesheet { $badge = this.css({ display: "inline-flex", alignItems: "center", gap: "0.375rem", borderRadius: "9999px", padding: "0.125rem 0.625rem", fontSize: "0.75rem", fontWeight: 500, }) .on('&[data-status="succeeded"]', { backgroundColor: "color-mix(in oklab, #10b981 10%, transparent)", color: "#10b981" }) .on('&[data-status="processing"]', { backgroundColor: t.muted, color: t.mutedForeground }) .on('&[data-status="failed"]', { backgroundColor: `color-mix(in oklab, ${t.destructive} 10%, transparent)`, color: t.destructive, }) .on('&[data-status="refunded"]', { backgroundColor: t.secondary, color: t.secondaryForeground }); $dot = this.css({ height: "0.375rem", width: "0.375rem", borderRadius: "9999px", backgroundColor: "currentColor" });}export type PaymentStatusValue = "succeeded" | "processing" | "failed" | "refunded";export interface PaymentStatusProps { status: PaymentStatusValue; class?: string;}const LABELS: Record<PaymentStatusValue, string> = { succeeded: "Succeeded", processing: "Processing", failed: "Failed", refunded: "Refunded",};@Component()export class PaymentStatus extends StatelessComponent<PaymentStatusProps> { @Styled(PaymentStatusStyles) $s!: PaymentStatusStyles; render() { const { status, class: cls } = this.props; 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. Unlike Badge (generic, no built-in semantics),
PaymentStatus hardcodes the four payment states and their colors/labels — pass the raw status
value and it renders correctly, no variant mapping needed on your end.
Usage
import { PaymentStatus } from "@/components/ui/payment-status";
<PaymentStatus status="succeeded" />
<PaymentStatus status="refunded" />Props
| Prop | Type | Default |
|---|---|---|
status | "succeeded" | "processing" | "failed" | "refunded" | — |
class | string | — |