{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "matrix-1",
  "title": "Matrix 1: service health by region",
  "author": "Ballmac <https://ui.ballmac.com>",
  "description": "Service health by region: 30-day availability for every service in every region as a heat grid, each cell good, warning or problem in words and an icon, what is below the line listed, the last incident per cell and a team filter.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "utils",
    "https://ui.ballmac.com/r/button.json",
    "https://ui.ballmac.com/r/heat-grid.json",
    "https://ui.ballmac.com/r/skeleton.json",
    "https://ui.ballmac.com/r/state-view.json"
  ],
  "files": [
    {
      "path": "registry/ballmac/components/blocks/matrix-1/matrix-1.tsx",
      "content": "// Ballmac UI: Matrix 1. https://ui.ballmac.com/blocks/matrix-1\n\"use client\"\n\nimport * as React from \"react\"\nimport { BookOpenCheck, CalendarClock } from \"lucide-react\"\n\nimport { Button } from \"@/components/ballmac/button\"\nimport { HeatGrid } from \"@/components/ballmac/heat-grid\"\nimport { Skeleton } from \"@/components/ballmac/skeleton\"\nimport { frameProps, StateView, type StateProps } from \"@/components/ballmac/state-view\"\nimport { cn } from \"@/lib/utils\"\n\ntype Matrix1Service = { id: string; name: string; team: string }\ntype Matrix1Region = { id: string; label: string }\ntype Matrix1Incident = { when: string; summary: string }\n\ntype Matrix1Props = Omit<React.ComponentProps<\"section\">, \"title\"> &\n  StateProps & {\n    services?: Matrix1Service[]\n    regions?: Matrix1Region[]\n    /** Availability over the last 30 days as a percentage, by service then region. null means the service does not run there. */\n    availability?: (number | null)[][]\n    /** The most recent incident for a service in a region, keyed \"serviceId:regionId\". */\n    incidents?: Record<string, Matrix1Incident>\n    title?: string\n    /** Availability at or above this is good; between this and `warnBelow` is a warning; below `warnBelow` is a problem. */\n    goodFrom?: number\n    warnBelow?: number\n    /** Called when someone opens the runbook for the selected service and region. */\n    onOpenRunbook?: (serviceId: string, regionId: string) => void\n  }\n\nconst services: Matrix1Service[] = [\n  { id: \"api\", name: \"API\", team: \"Platform\" },\n  { id: \"auth\", name: \"Sign-in\", team: \"Platform\" },\n  { id: \"pay\", name: \"Payments\", team: \"Billing\" },\n  { id: \"search\", name: \"Search\", team: \"Discovery\" },\n  { id: \"media\", name: \"Media\", team: \"Discovery\" },\n  { id: \"ai\", name: \"Assistant\", team: \"AI\" },\n]\nconst regions: Matrix1Region[] = [\n  { id: \"us\", label: \"US East\" },\n  { id: \"eu\", label: \"Europe\" },\n  { id: \"ap\", label: \"Asia Pacific\" },\n  { id: \"sa\", label: \"South America\" },\n]\nconst availability: (number | null)[][] = [\n  [99.99, 99.98, 99.95, 99.92],\n  [99.99, 99.99, 99.97, 99.9],\n  [99.97, 99.82, 99.93, null],\n  [99.94, 99.91, 99.2, 99.88],\n  [99.9, 99.96, 99.86, 99.4],\n  [99.6, 99.1, 98.4, null],\n]\nconst incidents: Record<string, Matrix1Incident> = {\n  \"pay:eu\": { when: \"17 Oct\", summary: \"Card payments failed for 38 minutes after a certificate expired on the European gateway.\" },\n  \"search:ap\": { when: \"21 Oct\", summary: \"The index fell behind by two hours and results were stale.\" },\n  \"ai:ap\": { when: \"22 Oct\", summary: \"Model calls from Asia Pacific timed out for most of an afternoon.\" },\n}\n\nfunction Skel() {\n  return (\n    <div aria-hidden=\"true\" className=\"grid gap-4\">\n      <Skeleton className=\"h-72 rounded-xl\" />\n      <Skeleton className=\"h-24 rounded-xl\" />\n    </div>\n  )\n}\n\n/**\n * Service health by region at a glance: availability over the last thirty days for every service in every region, each cell good, warning or problem in words\n * and an icon as well as a tint. Pick a cell for the last incident there and a button to open its runbook; filter the rows by team.\n */\nfunction Matrix1({ services: svc = services, regions: reg = regions, availability: values = availability, incidents: inc = incidents, title = \"Service health\", goodFrom = 99.9, warnBelow = 99, onOpenRunbook, state = \"ready\", onRetry, emptyState, errorState, className, ...props }: Matrix1Props) {\n  const id = React.useId()\n  const [team, setTeam] = React.useState(\"all\")\n  const [cell, setCell] = React.useState<[number, number] | null>(null)\n  const view = state === \"ready\" && svc.length === 0 ? \"empty\" : state\n  const teams = [...new Set(svc.map((s) => s.team))]\n  const rows = svc.map((s, i) => ({ s, i })).filter(({ s }) => team === \"all\" || s.team === team)\n  const shownValues = rows.map(({ i }) => values[i] ?? [])\n  const sel = cell ? { service: rows[cell[0]]?.s, region: reg[cell[1]], value: shownValues[cell[0]]?.[cell[1]] } : null\n  const problems = rows.flatMap(({ s, i }) => reg.map((r, c) => ({ s, r, v: values[i]?.[c] ?? null }))).filter((x) => x.v !== null && x.v < warnBelow)\n  const key = sel?.service && sel.region ? `${sel.service.id}:${sel.region.id}` : \"\"\n\n  return (\n    <section data-slot=\"matrix-1\" data-state={state} aria-labelledby={`${id}-title`} className={cn(\"mx-auto w-full max-w-5xl px-4 py-10 sm:px-6\", className)} {...frameProps(props)}>\n      <header className=\"mb-8 flex flex-wrap items-end justify-between gap-4\">\n        <div>\n          <h1 id={`${id}-title`} className=\"text-3xl font-semibold tracking-[-0.035em] text-balance\">\n            {title}\n          </h1>\n          <p className=\"text-muted-foreground mt-2 max-w-xl text-pretty\">Availability over the last 30 days, for every service in every region.</p>\n        </div>\n        {view === \"ready\" && teams.length > 1 && (\n          <label className=\"flex items-center gap-2 text-sm\">\n            <span className=\"text-muted-foreground\">Team</span>\n            <select value={team} onChange={(e) => { setTeam(e.target.value); setCell(null) }} className=\"bg-background focus-visible:ring-ring/50 h-9 rounded-md border px-2 text-sm outline-none focus-visible:ring-[3px]\">\n              <option value=\"all\">All teams</option>\n              {teams.map((t) => (\n                <option key={t}>{t}</option>\n              ))}\n            </select>\n          </label>\n        )}\n      </header>\n      <StateView state={view} onRetry={onRetry} label=\"Loading service health\" loading={<Skel />} empty={{ title: \"No services yet\", description: \"Register a service and its availability will appear here, region by region.\", ...emptyState }} error={{ title: \"Service health could not be loaded\", description: \"Nothing was changed. Check your connection and try again.\", ...errorState }}>\n        <p aria-live=\"polite\" className=\"text-muted-foreground mb-4 text-sm\">\n          {problems.length ? <><strong className=\"text-foreground\">{problems.length} {problems.length === 1 ? \"combination is\" : \"combinations are\"} below {warnBelow}%.</strong> {problems.map((p) => `${p.s.name} in ${p.r.label}`).join(\", \")}.</> : `Everything is at or above ${warnBelow}%.`}\n        </p>\n        <HeatGrid\n          rowLabel=\"Service\"\n          columnLabel=\"Region\"\n          rows={rows.map(({ s }) => ({ id: s.id, label: s.name }))}\n          columns={reg}\n          values={shownValues}\n          format={(v) => `${v}%`}\n          tone={(v) => (v >= goodFrom ? \"good\" : v >= warnBelow ? \"warn\" : \"bad\")}\n          selected={cell}\n          onSelectedChange={setCell}\n        />\n        <div aria-live=\"polite\" className=\"bg-card mt-4 min-h-[5.5rem] rounded-xl border p-4\">\n          {sel?.service && sel.region ? (\n            <div className=\"flex flex-wrap items-start justify-between gap-3\">\n              <div className=\"min-w-0\">\n                <p className=\"font-medium\">{sel.service.name} in {sel.region.label} <span className=\"text-muted-foreground font-normal\">· {sel.service.team}</span></p>\n                <p className=\"text-muted-foreground mt-0.5 text-sm tabular-nums\">{sel.value === null || sel.value === undefined ? \"This service does not run in this region.\" : `${sel.value}% available over 30 days`}</p>\n                {inc[key] ? (\n                  <p className=\"mt-2 flex max-w-xl gap-2 text-sm\"><CalendarClock aria-hidden=\"true\" className=\"mt-0.5 size-4 shrink-0\" /><span><span className=\"font-medium\">Last incident, {inc[key].when}:</span> {inc[key].summary}</span></p>\n                ) : sel.value !== null && sel.value !== undefined ? (\n                  <p className=\"text-muted-foreground mt-2 text-sm\">No incident recorded here in the last 30 days.</p>\n                ) : null}\n              </div>\n              {sel.value !== null && sel.value !== undefined && (\n                <Button size=\"sm\" variant=\"outline\" onClick={() => onOpenRunbook?.(sel.service!.id, sel.region.id)}>\n                  <BookOpenCheck aria-hidden=\"true\" /> Open runbook\n                </Button>\n              )}\n            </div>\n          ) : (\n            <p className=\"text-muted-foreground text-sm\">Select a cell for the last incident there. The arrow keys move between cells.</p>\n          )}\n        </div>\n      </StateView>\n    </section>\n  )\n}\n\nexport { Matrix1, type Matrix1Incident, type Matrix1Props, type Matrix1Region, type Matrix1Service }\n",
      "type": "registry:component",
      "target": "@components/ballmac/blocks/matrix-1/matrix-1.tsx"
    }
  ],
  "meta": {
    "schema": 1,
    "tier": "free",
    "tags": [
      "service health",
      "availability",
      "regions",
      "heatmap",
      "uptime",
      "sre",
      "status",
      "reliability"
    ],
    "version": "1.0.0",
    "updated": "2026-10-24",
    "tests": true,
    "ai": {
      "summary": "Service health by region. <Matrix1 services={[{ id, name, team }]} regions={[{ id, label }]} availability={[[99.99, 99.8, null], ...]} incidents={{ 'pay:eu': { when, summary } }} goodFrom={99.9} warnBelow={99} onOpenRunbook={(serviceId, regionId) => void} />. Built on heat-grid with tone. Cells at or above goodFrom are good, below warnBelow are problems; null means the service does not run there.",
      "whenToUse": [
        "A reliability overview across services and regions",
        "A status board for an engineering team"
      ],
      "whenNotToUse": [
        "A public status page; use status-1",
        "Error budgets over time; use slo-1"
      ],
      "composesWith": [
        "slo-1",
        "incident-1",
        "runbook-1",
        "status-1"
      ],
      "a11y": [
        {
          "keys": "Grid",
          "action": "An ARIA grid with row and column headers; Tab enters once and the arrow keys, Home and End move between cells"
        },
        {
          "keys": "Cells",
          "action": "Each reads 'Payments, Europe: 99.82%, Warning'; tone adds an icon and a word, never colour alone"
        },
        {
          "keys": "Summary",
          "action": "What is below the line is written as a sentence in a polite live region"
        },
        {
          "keys": "Detail",
          "action": "The chosen cell's last incident and an Open runbook button"
        }
      ],
      "customization": [
        "services, regions and availability",
        "goodFrom and warnBelow",
        "incidents keyed 'serviceId:regionId'",
        "onOpenRunbook"
      ]
    },
    "states": [
      {
        "id": "loading",
        "title": "Loading",
        "example": "matrix-1-loading",
        "trigger": "state=\"loading\"",
        "note": "Skeleton for the grid and the detail under the real heading, announced as loading."
      },
      {
        "id": "empty",
        "title": "No services yet",
        "example": "matrix-1-empty",
        "trigger": "state=\"empty\"",
        "note": "Says no services yet; emptyState sets the copy."
      },
      {
        "id": "error",
        "title": "Could not load",
        "example": "matrix-1-error",
        "trigger": "state=\"error\"",
        "note": "An alert saying nothing was changed, with Try again (onRetry)."
      }
    ],
    "examples": [
      "matrix-1-demo",
      "matrix-1-ai",
      "matrix-1-loading",
      "matrix-1-empty",
      "matrix-1-error"
    ],
    "url": "https://ui.ballmac.com/components/matrix-1"
  },
  "categories": [
    "blocks",
    "matrix"
  ],
  "type": "registry:block"
}