KKiotaPay UI
Browse documentation

Status Badge

A payment status pill built on the shadcn Badge. Each state maps onto a shared colour ramp — success, warning, danger, info — so the same meaning renders the same way everywhere in the product.

Installation

pnpm dlx shadcn@latest add https://kiotapay-ui-staging.staging.kiotapay.com/r/status-badge.json

Usage

import { StatusBadge } from '@/components/custom/status-badge'

export function PaymentRow() {
  return <StatusBadge status="success" />
}

Props

Extends React.ComponentProps<typeof Badge> minus variant and children.

PropTypeDefaultDescription
statusPaymentStatus—One of success, pending, failed, refunded, neutral.
labelReactNodefrom STATUS_LABELSReplaces the default wording.
withDotbooleantrueShow the leading dot. Turn off in dense tables.
size'sm' | 'md''md'Pill size.

Exports

ExportDescription
StatusBadgeThe component.
PaymentStatusUnion type of the five statuses.
PAYMENT_STATUSESReadonly array of every status, for iteration.
STATUS_LABELSDefault label per status.
statusBadgeVariantsThe underlying cva function, for composing elsewhere.

Examples

In a table

Dense rows read better at size="sm" with the dot suppressed — the column position already establishes what the value means.

Custom labels

The status drives colour; the label is free text. Use this when a surface has its own vocabulary — a refund queue calling success "Settled", say.

<StatusBadge status="success" label="Settled" />
<StatusBadge status="pending" label="Awaiting M-Pesa" />
<StatusBadge status="neutral" label="Not submitted" />

Accessibility

Colour alone fails WCAG 1.4.1, so the label always ships alongside the pill and the dot only reinforces it. Removing the text and keeping the dot would leave the state unreadable to anyone who cannot distinguish the hues — if you need a compact form, use size="sm" rather than dropping the label.

Theming

Payment states do not own colours. They map onto the shared state ramps installed by kiota-theme, so one hue means one thing everywhere in the product:

StatusRampRenders as
successsuccessbg-success-light text-success
pendingwarningbg-warning-light text-warning
faileddangerbg-danger-light text-danger
refundedinfobg-info-light text-info
neutralshadcn mutedbg-muted text-muted-foreground

Each ramp is three tokens in both themes — the solid colour, a readable -foreground for text on the solid, and a -light tint used as a surface. Recolour a state by redefining them after the import that declares them:

:root {
  --success: oklch(0.52 0.13 155);
  --success-foreground: oklch(0.985 0 0);
  --success-light: oklch(0.95 0.05 155);
}

.dark {
  --success: oklch(0.8 0.14 155);
  --success-foreground: oklch(0.2 0.04 155);
  --success-light: oklch(0.28 0.06 155);
}

Because these are real Tailwind theme colours, the utilities work anywhere in your app — bg-success, text-danger, border-warning/25 — not just inside this component.

Keep roughly 0.4 OKLCH lightness between a ramp's solid and its -light tint. The component pairs them as text on surface, and a closer pair drops below 4.5:1 at badge sizes even though it still looks like two distinct colours.

Badges rendering unstyled means the tokens never reached your stylesheet. Re-run the add command. Note that cssVars are applied at install time and re-runs do not reliably update existing variables — see Updating.