zzzUI

Feed

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/feed

示例

陆续出现的事件

  1. Rook picked up two power cells
  2. Sable-9 delivered a sealed crate
feed-events.tsx
import { useState } from "react";import { Button } from "@/components/zero/button";import { Feed, FeedActor, FeedItem, FeedTarget } from "@/components/zero/feed";type Event = {  id: number;  tone: "default" | "accent" | "danger" | "legendary";  who: string;  did: string;  what: string;  stays?: boolean;};const more: Omit<Event, "id">[] = [  { tone: "accent", who: "You", did: "delivered", what: "a sealed crate" },  { tone: "danger", who: "Patrol", did: "spotted", what: "Juniper" },  { tone: "legendary", who: "Nightjar", did: "found", what: "the gate key" },  { tone: "default", who: "Tallow", did: "joined", what: "the shift" },];export default function FeedEvents() {  const [events, setEvents] = useState<Event[]>([    {      id: 1,      tone: "default",      who: "Rook",      did: "picked up",      what: "two power cells",      stays: true,    },    {      id: 2,      tone: "accent",      who: "Sable-9",      did: "delivered",      what: "a sealed crate",      stays: true,    },  ]);  const [next, setNext] = useState(3);  return (    <div className="grid w-full max-w-md justify-items-end gap-5">      <Feed aria-label="Events" className="min-h-40 content-end">        {events.map((e) => (          <FeedItem            key={e.id}            tone={e.tone}            duration={e.stays ? 0 : 5000}            onExpire={() =>              setEvents((list) => list.filter((x) => x.id !== e.id))            }          >            <FeedActor>{e.who}</FeedActor> {e.did}{" "}            <FeedTarget>{e.what}</FeedTarget>          </FeedItem>        ))}      </Feed>      <Button        size="sm"        variant="secondary"        onClick={() => {          setEvents((list) => [            ...list.slice(-4),            { id: next, ...more[next % more.length] },          ]);          setNext((n) => n + 1);        }}      >        Something happens      </Button>    </div>  );}

行为

每条事件是一道向左渐隐的深色横条,一侧边缘以该条的色调着色,从右侧滑入;最新的一条在最下方。经过 duration 后调用 onExpire:将该条从列表中移除,它就会收起,其余条目随之合拢。

列表是 polite 级别的实时区域,每条新事件只读出一次。FeedActor 以展示字体和该条的色调标出执行者;FeedTarget 标出作用对象。开启「减少动态效果」时,事件直接出现和消失,不再滑动。

属性

FeedItem

属性类型默认值说明
tone"default" | "accent" | "danger" | "rare" | "legendary""default"边缘颜色,以及执行者的颜色。
durationnumber5000触发 onExpire 前的毫秒数;为 0 时常驻。
onExpire() => void—应移除该条目时调用。

Feed, FeedActor, FeedTarget