{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "ticker-tape",
  "type": "registry:component",
  "title": "Ticker Tape",
  "description": "Marquee-style scrolling symbol tape with price and change badges.",
  "dependencies": [
    "@vllnt/ui@^0.2.1"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/default/ticker-tape/ticker-tape.tsx",
      "content": "import * as React from \"react\";\n\nimport { ArrowDownRight, ArrowUpRight, Dot } from \"lucide-react\";\n\nimport { cn } from \"@vllnt/ui\";\nimport { Badge } from \"@vllnt/ui\";\n\nexport type TickerTapeItem = {\n  change: number;\n  price: number | string;\n  symbol: string;\n  volume?: string;\n};\n\nexport type TickerTapeProps = {\n  items: TickerTapeItem[];\n  pauseOnHover?: boolean;\n  speedSeconds?: number;\n} & React.HTMLAttributes<HTMLDivElement>;\n\nconst tickerTapeKeyframes = `\n@keyframes ticker-tape-scroll {\n  from {\n    transform: translateX(0);\n  }\n\n  to {\n    transform: translateX(-50%);\n  }\n}\n`;\n\nfunction formatPrice(price: number | string) {\n  return typeof price === \"number\" ? price.toLocaleString() : price;\n}\n\nfunction formatChange(change: number) {\n  const sign = change > 0 ? \"+\" : \"\";\n  return `${sign}${change.toFixed(2)}%`;\n}\n\nfunction TickerTapeRow({ items }: { items: TickerTapeItem[] }) {\n  return (\n    <div className=\"flex min-w-max items-center gap-3 p-3\">\n      {items.map((item) => {\n        const isPositive = item.change >= 0;\n        const TrendIcon = isPositive ? ArrowUpRight : ArrowDownRight;\n\n        return (\n          <div\n            className=\"flex min-w-[12rem] items-center gap-3 rounded-full border border-border/70 bg-background/80 px-3 py-2 shadow-sm\"\n            key={`${item.symbol}-${item.price}-${item.change}`}\n          >\n            <div className=\"flex min-w-0 flex-col\">\n              <span className=\"text-xs font-medium uppercase tracking-[0.24em] text-muted-foreground\">\n                {item.symbol}\n              </span>\n              <span className=\"truncate text-sm font-semibold text-foreground\">\n                {formatPrice(item.price)}\n              </span>\n            </div>\n            <Badge\n              className={cn(\n                \"ml-auto gap-1 rounded-full border px-2 py-0.5 text-[11px] tabular-nums\",\n                isPositive\n                  ? \"border-emerald-500/30 bg-emerald-500/10 text-emerald-600 dark:text-emerald-400\"\n                  : \"border-rose-500/30 bg-rose-500/10 text-rose-600 dark:text-rose-400\",\n              )}\n              variant=\"outline\"\n            >\n              <TrendIcon className=\"size-3\" />\n              {formatChange(item.change)}\n            </Badge>\n            {item.volume ? (\n              <span className=\"hidden items-center text-xs text-muted-foreground sm:inline-flex\">\n                <Dot className=\"size-3.5\" />\n                {item.volume}\n              </span>\n            ) : null}\n          </div>\n        );\n      })}\n    </div>\n  );\n}\n\nexport const TickerTape = React.forwardRef<HTMLDivElement, TickerTapeProps>(\n  (\n    { className, items, pauseOnHover = true, speedSeconds = 28, ...props },\n    reference,\n  ) => {\n    if (items.length === 0) {\n      return null;\n    }\n\n    return (\n      <div\n        aria-label=\"TickerTape\"\n        className={cn(\n          \"relative overflow-hidden rounded-2xl border border-border bg-card/70 backdrop-blur-sm\",\n          className,\n        )}\n        ref={reference}\n        role=\"region\"\n        {...props}\n      >\n        <style>{tickerTapeKeyframes}</style>\n        <div\n          className={cn(\n            \"flex w-max items-stretch\",\n            pauseOnHover && \"hover:[animation-play-state:paused]\",\n          )}\n          style={{\n            animationDuration: `${speedSeconds}s`,\n            animationIterationCount: \"infinite\",\n            animationName: \"ticker-tape-scroll\",\n            animationTimingFunction: \"linear\",\n          }}\n        >\n          <TickerTapeRow items={items} />\n          <div aria-hidden=\"true\">\n            <TickerTapeRow items={items} />\n          </div>\n        </div>\n      </div>\n    );\n  },\n);\n\nTickerTape.displayName = \"TickerTape\";\n",
      "type": "registry:component"
    }
  ],
  "version": "0.2.1",
  "stability": "stable"
}
