Brand

Server status

A network or city status pill: dot, label, count.

stablev0.1.0 Chromium 103 ui-scale safe

Install

Copies the file into components/ds/, with its registry dependencies and npm packages. See Installation for the one-time setup.
bunx shadcn@3 add @fastrp/server-status

Examples

Default

Open alone
Tüm şehirler açık2/2Bir şehir bakımda1/2Durum okunamadıLos Santos248/300

API

<ServerStatus />

A network or city status pill: a live dot, a label and an optional count. It shows whatever it is given — fetching the health and translating the label stay with the app, and a failed read should be shown as `offline`, not hidden: that is when a visitor needs it.

PropTypeDefaultNotes
label*ReactNode—What the status means, in the app's language: "Tüm şehirler açık".
status*NonNullable<"partial" | "online" | "offline" | "checking" | null | undefined>—
appearance"glass" | "plain"glass`glass` for over footage; `plain` on a surface.
count{ value: number; of?: number; }—A count beside the label: `{ value: 248, of: 300 }` reads "248/300".

Dependencies

npm

  • None

Registry

Source

components/ds/server-status.tsxShow
import type * as React from 'react';
import { StatusDot, type StatusDotProps } from '@/components/ds/status-dot';
import { cn } from '@/lib/utils';

// @fast-ds [email protected]

export type ServerStatusProps = Omit<React.ComponentProps<'output'>, 'children'> & {
  status: NonNullable<StatusDotProps['status']>;
  /** What the status means, in the app's language: "Tüm şehirler açık". */
  label: React.ReactNode;
  /** A count beside the label: `{ value: 248, of: 300 }` reads "248/300". */
  count?: { value: number; of?: number };
  /** `glass` for over footage; `plain` on a surface. */
  appearance?: 'glass' | 'plain';
};

/**
 * A network or city status pill: a live dot, a label and an optional count. It shows whatever it
 * is given — fetching the health and translating the label stay with the app, and a failed read
 * should be shown as `offline`, not hidden: that is when a visitor needs it.
 */
function ServerStatus({
  status,
  label,
  count,
  appearance = 'glass',
  className,
  ...props
}: ServerStatusProps) {
  return (
    // <output> is a live status region by default, so a change of state is announced.
    <output
      data-slot="server-status"
      className={cn(
        'inline-flex items-center gap-2.5 px-4 py-2 text-xs font-medium text-foreground/80',
        appearance === 'glass' ? 'glass' : 'border border-line bg-surface',
        className,
      )}
      {...props}
    >
      <StatusDot status={status} pulse={status === 'online'} />
      <span>{label}</span>
      {count && (
        <span className="tabular-nums text-muted-foreground">
          {count.value}
          {count.of !== undefined && `/${count.of}`}
        </span>
      )}
    </output>
  );
}

export { ServerStatus };