Skip to content
Components

Status tray

A footer row of readout chips; one opens a small tray above it at a time.

TS
import { … } from "@fungi.computer/caps/blocks/status-tray";

Hero

TSX
import {
StatusTray,
StatusTrayList,
StatusTrayRow,
type StatusTrayItem,
} from "@fungi.computer/caps/blocks/status-tray";
import { useState } from "react";
export default function Hero() {
const [openId, setOpenId] = useState<string | null>("batches");
const items: StatusTrayItem[] = [
{
id: "batches",
label: "Batches",
count: 2,
tone: "success",
content: (
<StatusTrayList>
<StatusTrayRow primary="Lion's Mane" secondary="Day 6 of 10" />
<StatusTrayRow primary="Oyster" secondary="Day 2 of 10" />
</StatusTrayList>
),
},
{
id: "alerts",
label: "Alerts",
tone: "warning",
content: <p className="caps-status-tray-note">All clear.</p>,
},
];
return <StatusTray items={items} openId={openId} onOpenChange={setOpenId} />;
}

Empty and disabled

TSX
import {
StatusTray,
StatusTrayNote,
type StatusTrayItem,
} from "@fungi.computer/caps/blocks/status-tray";
import { useState } from "react";
export default function EmptyAndDisabled() {
const [openId, setOpenId] = useState<string | null>("alerts");
const items: StatusTrayItem[] = [
{ id: "alerts", label: "Alerts", content: <StatusTrayNote /> },
{
id: "computer",
label: "Computer",
disabled: true,
accessibleLabel: "Computer unavailable",
content: null,
},
];
return <StatusTray items={items} openId={openId} onOpenChange={setOpenId} />;
}

Props

StatusTrayProps

PropTypeDescription
itemsreadonly StatusTrayItem[]Readouts and their tray contents in display order.
openIdstring | nullWhich tray is open. The host owns this state.
onOpenChange()(id) => voidRequests a selection change or dismissal.
leading?ReactNodeLeading readouts that never open a tray (connection state, etc.).
trailing?ReactNodeTrailing controls after the chips (Send, Expand, …).
placement?"housing" | "screen" | "host"Structural seat. housing sits on the plastic below a screen; screen sits inside a Display as flat, screen-native text (the wiki's screen material rule); host means a host's own chrome draws the chips, so only the open tray renders here. The look of each seat is theme-owned.
align?"start" | "end"Which edge the tray aligns to.
hostInset?numberFor host placement: where the host's trigger starts, in CSS pixels from this tray's inline start, so the open tray sits above it.
  • itemsreadonly StatusTrayItem[]

    Readouts and their tray contents in display order.

  • openIdstring | null

    Which tray is open. The host owns this state.

  • onOpenChange()(id) => void

    Requests a selection change or dismissal.

  • leading?ReactNode

    Leading readouts that never open a tray (connection state, etc.).

  • trailing?ReactNode

    Trailing controls after the chips (Send, Expand, …).

  • placement?"housing" | "screen" | "host"

    Structural seat. housing sits on the plastic below a screen; screen sits inside a Display as flat, screen-native text (the wiki's screen material rule); host means a host's own chrome draws the chips, so only the open tray renders here. The look of each seat is theme-owned.

  • align?"start" | "end"

    Which edge the tray aligns to.

  • hostInset?number

    For host placement: where the host's trigger starts, in CSS pixels from this tray's inline start, so the open tray sits above it.

Full types: API reference.