Skip to content

Status & health

Is everything all right: status over 90 days, queues, tile boards and a score with what is open.

Installation & usage

npx @youj/cli add app-status

Also installs alert, async-button, badge, button, card, counter, dropdown-menu, empty, history-strip, icon-more-horizontal, segmented-meter, skeleton, typography, use-controllable-state, youj-core, youj-presets, youj-ui-core.

The CLI copies the block to blocks/app/status.tsx with every component it uses, so it’s yours to edit.

Every prop is optional and falls back to the demo, so it renders as you see it until you pass your own. Give it your data, rewrite or translate its strings through copy, and connect its actions:

statusCard-view.tsx
'use client'

import { StatusCard, type StatusCardProps } from '@/blocks/app/status'

export function StatusCardView({ services, statuses }: Pick<StatusCardProps, 'services' | 'statuses'>) {
  return (
    <StatusCard
      services={services}
      statuses={statuses}
      copy={{ title: 'Status' }}
      onValueChange={(id) => {
        // your code
      }}
      onRetry={() => {
        // your code
      }}
      onSubscribe={async () => {
        // await your API here; the block shows progress until it settles
      }}
    />
  )
}

Reference

Props23 props, 2 types

Props

StatusCard props
PropType
themeThemeInput

Wraps the card in this theme. Default: the theme around it.

–
embeddedboolean

Inside another app: a section named by an h2, without the page around the card.

default true

true
fillboolean

Take the whole width it's given instead of stopping at its natural width (640px at 100% scale).

default false

false
copyPartial<StatusCopy>

Any of the card's strings, to rewrite or translate.

–
headingLevel1 | 2 | 3

The title's heading level. Default 1, or 2 when embedded.

–
localestring

Formats percentages and "days ago". Default: copy.locale, else the app's locale (YoujProvider), else en-US.

–
servicesStatusService[]

Each service with a day per entry, oldest first, the last today. Default: six demo services.

–
todayDate | string

The day the services' last entry is, as a Date or "YYYY-MM-DD"; "days ago" counts from it, and the demo fleet ends on it. Default: the last day in services (the demo's Sep 28, 2026).

–
statusesStatusLevel[]

The statuses a service can be in, best first: a day at or above the target is the first, one above the critical line the second, anything below the last. A service's own status (an id) overrides that.

default operational, degraded, outage

operational, degraded, outage
criticalnumber

The uptime below which a day is an outage, 0–1, always under target.

default 0.99

0.99
format{ uptime?: (share: number) => string }

Formats the uptime shares (0–1) in the figure, the target, the legend and the rows. Default: percentages in the locale.

–
targetnumber

The SLA a day must meet, 0–1.

default 0.999

0.999
valuestring | null

The id of the service on the day strip, or null for all of them; pair with onValueChange.

–
defaultValuestring | null

The service on the day strip at first.

default null

null
onValueChange(id: string | null) => void

Called with the service id pressed, or null when it's pressed again.

–
loadingboolean

Shows skeletons in place of the figures, strip and services.

default false

false
errorReactNode | Error

Shown in place of the figures when loading failed; an Error shows its message.

–
onRetry() => void

Offers a retry beside error.

–
emptyReactNode

Replaces the empty state shown when there are no services.

default `copy.empty`

`copy.empty`
onSubscribe() => Promise<unknown> | unknown

Subscribes to updates; resolve when done, reject with an Error to show its message. Default: a short demo wait that warns once in development.

–
onCopyLink() => void

The menu's Copy status link. Default: nothing.

–
onExport() => void

The menu's Export CSV. Default: nothing.

–
onHistory() => void

The Incident history button. Default: nothing.

–

StatusLevel

StatusLevel props
PropType
idRequiredstring–
labelRequiredstring–
toneRequired'accent' | 'info' | 'success' | 'warning' | 'danger'–

StatusService

StatusService props
PropType
idRequiredstring–
nameRequiredstring

Set in mono.

–
daysRequiredUptimeDay[]

One entry per day, oldest first; the last is today.

–
statusstring

A StatusLevel id, to say its status instead of reading it from today's uptime.

–
Strings28 keys for copy

Strings

copy takes any of these keys; the rest keep their defaults. A key whose text holds a value (a count, a name) takes a function.

titlesubtitlemorecopyLinkexportCsvuptimetargetoperationalpartialbudgetdailyallServicesstripLabelshowAllnoDataservicesservicesSummarylastIncidentongoinghistorysubscribesubscribingsubscribedfailedemptyemptyDescriptionretrylocale
Built from11 components
Accessibilitystatus, buttons, labels, motion

Accessibility

Status gives each service button a spoken label of its name, state and uptime, with aria-pressed for the one you picked and a labelled remove control on the filter badge. Errors use role="alert".

The queue picker in Queue monitor is a labelled segmented control. The status line does not announce each tick.

Tile board makes every tile a button (aria-pressed) whose name includes its status in words; the colored bar only echoes it. The alert timer is a role="timer" that is not announced every second, the reason is one named choice, and Escalate now and Resolve announce their result in a polite live region. Timers stop in a hidden tab.

Score overview puts the score on a meter named Security score whose value text is the score and its grade ("77 of 100, grade B"), and each figure is a group named by its label. The tabs are a named tab list; the chart is a named figure with a summary of how the open findings moved, its plot one tab stop whose arrow keys walk the days and open the tooltip. Every finding is a button named with its severity, title, asset and how long it has been open, and every asset says its counts by severity in words. A scan is announced when it finishes, and the foot's progress is a polite live region. The stories show other worlds, with their own names and words.

Under reduced motion figures, bars, rings and rows are drawn in place instead of animating, and nothing loops.