Components
Item grid
A backpack you can drive from the keyboard: footprints, stacks, a drop ghost that says why not, and equipment slots.
import { โฆ } from "@fungi.computer/caps/components/item-grid";Backpack
import { ItemGrid, type ItemGridItem,} from "@fungi.computer/caps/components/item-grid";
const items: ItemGridItem[] = [ { id: "axe", label: "Axe", x: 0, y: 0, h: 2, icon: "๐ช" }, { id: "log", label: "Oak log", x: 1, y: 0, quantity: 3, icon: "๐ชต" }, { id: "bread", label: "Bread", x: 2, y: 0, quantity: 2, icon: "๐" }, { id: "spores", label: "Spore syringe", x: 1, y: 1, icon: "๐งช" },];
export default function Backpack() { return <ItemGrid label="Backpack" columns={4} rows={2} items={items} />;}Equipment slots
import { ItemSlot } from "@fungi.computer/caps/components/item-grid";
export default function EquipmentSlots() { return ( <div className="flex flex-wrap gap-2"> <ItemSlot label="Head" item={{ label: "Straw hat", icon: "๐" }} /> <ItemSlot label="Main hand" item={{ label: "Axe", icon: "๐ช" }} /> <ItemSlot label="Pack" state="legal" placeholder="๐ฆ" /> <ItemSlot label="Belt" state="illegal" /> <ItemSlot label="Feet" disabled /> </div> );}Drop ghost
import { ItemGrid, type ItemGridItem,} from "@fungi.computer/caps/components/item-grid";import { useState } from "react";
const items: ItemGridItem[] = [ { id: "log", label: "Oak log", x: 0, y: 0, h: 2, icon: "๐ชต" },];
export default function DropGhost() { const [message, setMessage] = useState("Hover a cell to preview a drop."); return ( <div className="flex flex-col gap-2"> <ItemGrid label="Shelf" columns={4} rows={2} items={items} onCellHover={(cell) => { if (!cell) return; setMessage( cell.item ? `${cell.item.label} is here already.` : "That cell is free.", ); }} /> <p role="status">{message}</p> </div> );}Props
ItemGridProps
| Prop | Type | Description |
|---|---|---|
label | string | Accessible name of the container, e.g. "Backpack". |
columns | number | |
rows | number | |
items | readonly ItemGridItem[] | |
ghost? | ItemGridGhost | | |
cellSize? | "sm" | | |
activeCell? | object | Controlled keyboard cursor. Omit to let the grid keep its own. |
activeCell.x | number | |
activeCell.y | number | |
onActiveCellChange()? | (cell) => void | The keyboard cursor moved to another cell. |
onCellActivate()? | (cell) => void | Click, Enter or Space on a cell. The host decides pick up, drop or use. |
onCellHover()? | (cell) => void | Pointer over a cell, or null on leaving the grid; for drag ghosts. |
labelstringAccessible name of the container, e.g. "Backpack".
columnsnumberrowsnumberitemsreadonly ItemGridItem[]ghost?ItemGridGhost |null cellSize?"sm" |"md" | "lg" activeCell?objectControlled keyboard cursor. Omit to let the grid keep its own.
activeCell.xnumberactiveCell.ynumberonActiveCellChange()?(cell) => voidThe keyboard cursor moved to another cell.
onCellActivate()?(cell) => voidClick, Enter or Space on a cell. The host decides pick up, drop or use.
onCellHover()?(cell) => voidPointer over a cell, or null on leaving the grid; for drag ghosts.
ItemSlotProps
| Prop | Type | Description |
|---|---|---|
label | string | Slot name, e.g. "Head" or "Main hand". |
item? | { label: string; icon?: ReactNode; } | | The equipped item, if any. |
placeholder? | ReactNode | Faint outline art shown while the slot is empty. |
state? | "idle" | |
labelstringSlot name, e.g. "Head" or "Main hand".
item?{ label: string; icon?: ReactNode; } |null The equipped item, if any.
placeholder?ReactNodeFaint outline art shown while the slot is empty.
state?"idle" |"legal" | "illegal"
Full types: API reference.