zzzUI

Inventory

React 物品栏组件:方形格子带稀有度光晕,角落显示数量,冷却以扇形遮罩显示,可用方向键在格子间移动。

安装

terminal
# once per project: where @zzzui items come frompnpm dlx shadcn@latest registry add @zzzui=https://zzzui.catforest.dev/r/{name}.jsonpnpm dlx shadcn@latest add @zzzui/inventory

示例

货舱

Sealed crate · 2 in the hold · rare

inventory-hold.tsx
import { useState } from "react";import {  CellIcon,  ChipIcon,  CrateIcon,  FlareIcon,  KeyIcon,  KitIcon,} from "@/components/zero/icons";import { Inventory, InventorySlot } from "@/components/zero/inventory";const cargo = [  { name: "Sealed crate", icon: CrateIcon, rarity: "rare", count: 2 },  { name: "Power cell", icon: CellIcon, rarity: "uncommon", count: 6 },  { name: "Signal flare", icon: FlareIcon, rarity: "common", count: 12 },  { name: "Gate key", icon: KeyIcon, rarity: "legendary", count: 1 },  { name: "Route chip", icon: ChipIcon, rarity: "epic", count: 1 },  { name: "Repair kit", icon: KitIcon, rarity: "uncommon", count: 3 },  { name: "Spare cell", icon: CellIcon, rarity: "common", count: 2 },] as const;export default function InventoryHold() {  const [chosen, setChosen] = useState(0);  const item = cargo[chosen];  return (    <div className="grid gap-4">      <Inventory columns={6} aria-label="Cargo hold">        {cargo.map((thing, index) => (          <InventorySlot            key={thing.name}            rarity={thing.rarity}            count={thing.count}            selected={index === chosen}            cooldown={thing.name === "Repair kit" ? 0.6 : undefined}            aria-label={`${thing.name}, ${thing.count}`}            onClick={() => setChosen(index)}          >            <thing.icon />          </InventorySlot>        ))}        {Array.from({ length: 11 }, (_, index) => (          // biome-ignore lint/suspicious/noArrayIndexKey: empty slots have nothing else to tell them apart          <InventorySlot key={index} aria-label="Empty" />        ))}      </Inventory>      <p className="font-medium font-zero-text text-zero-sm text-zero-text-2">        <span className="font-bold font-zero text-zero-text italic">          {item.name}        </span>{" "}        · {item.count} in the hold · {item.rarity}      </p>    </div>  );}

行为

每个格子是一道黑色底槽,带一条暗色细边。rarity 以对应稀有度的颜色点亮格子底边,并从底边向上泛起光晕;selected 以强调色框住格子;cooldown(剩余比例,0–1)像时钟一样,将一整圈中相应比例的扇区遮暗;空格子显示斜线纹理。数量大于 1 时显示在角落。

整个网格在 Tab 顺序中只占一个位置。按方向键可在格子之间上下左右移动,按 Home、End 可跳到一行的首尾,配合 Ctrl 则跳到整个物品栏的首尾;再次按 Tab 进入时,回到上次停留的格子。每个格子都是按钮:需为每个格子提供说明所装物品的 aria-label,并为物品栏本身提供名称。格子尺寸由 --zero-slot 决定。

示例中的物品图案均为 zzzUI 自带的物品图标:箱子、能量电池、信号弹、钥匙、芯片和维修包。

属性

Inventory

属性类型默认值说明
columnsnumber6每行的格数;方向键上下移动时以此为步长。

InventorySlot

属性类型默认值说明
rarity"common" | "uncommon" | "rare" | "epic" | "legendary"—以对应稀有度的颜色点亮底边与光晕。
selectedboolean—以强调色框住格子(aria-pressed)。
countnumber—大于 1 时显示在角落。
cooldownnumber—冷却的剩余比例,0–1。
childrenReactNode—格中物品;为空时显示斜线纹理。

另可传入 Base UI Button 的全部属性。