{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "watchlist",
  "type": "registry:component",
  "title": "Watchlist",
  "description": "Tracked-symbol list with price, change, and advancing/declining summary.",
  "dependencies": [
    "@vllnt/ui@^0.2.1"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/default/watchlist/watchlist.tsx",
      "content": "import * as React from \"react\";\n\nimport { ArrowDownRight, ArrowUpRight, Star } from \"lucide-react\";\n\nimport { cn } from \"@vllnt/ui\";\n\nexport type WatchlistItem = {\n  change: number;\n  name?: string;\n  price: number | string;\n  starred?: boolean;\n  symbol: string;\n  volume?: string;\n};\n\nexport type WatchlistProps = {\n  eyebrow?: string;\n  items: WatchlistItem[];\n  title?: string;\n} & React.HTMLAttributes<HTMLDivElement>;\n\nfunction formatPrice(price: number | string): string {\n  return typeof price === \"number\"\n    ? price.toLocaleString(undefined, {\n        maximumFractionDigits: 2,\n        minimumFractionDigits: 2,\n      })\n    : price;\n}\n\nfunction formatChange(change: number): string {\n  const sign = change > 0 ? \"+\" : \"\";\n  return `${sign}${change.toFixed(2)}%`;\n}\n\nfunction WatchlistRow({ item }: { item: WatchlistItem }): React.JSX.Element {\n  const isPositive = item.change >= 0;\n  const TrendIcon = isPositive ? ArrowUpRight : ArrowDownRight;\n\n  return (\n    <li className=\"grid grid-cols-[auto_minmax(0,1fr)_auto_auto] items-center gap-3 rounded-xl px-3 py-2.5 transition-colors hover:bg-muted/40\">\n      <span\n        aria-hidden=\"true\"\n        className={cn(\n          \"flex size-7 items-center justify-center rounded-full border\",\n          item.starred\n            ? \"border-amber-400/40 bg-amber-400/10 text-amber-500\"\n            : \"border-border bg-background text-muted-foreground\",\n        )}\n      >\n        <Star\n          className={cn(\"size-3.5\", item.starred && \"fill-current\")}\n          strokeWidth={1.75}\n        />\n      </span>\n      <div className=\"min-w-0\">\n        <p className=\"truncate text-sm font-semibold text-foreground\">\n          {item.symbol}\n        </p>\n        {item.name ? (\n          <p className=\"truncate text-xs text-muted-foreground\">{item.name}</p>\n        ) : null}\n      </div>\n      <div className=\"text-right\">\n        <p className=\"text-sm font-semibold tabular-nums text-foreground\">\n          {formatPrice(item.price)}\n        </p>\n        {item.volume ? (\n          <p className=\"text-[11px] text-muted-foreground tabular-nums\">\n            {item.volume}\n          </p>\n        ) : null}\n      </div>\n      <span\n        className={cn(\n          \"inline-flex items-center gap-1 rounded-full border px-2 py-1 text-xs font-medium 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      >\n        <TrendIcon className=\"size-3\" />\n        {formatChange(item.change)}\n      </span>\n    </li>\n  );\n}\n\nexport const Watchlist = React.forwardRef<HTMLDivElement, WatchlistProps>(\n  (\n    {\n      className,\n      eyebrow = \"Tracked symbols\",\n      items,\n      title = \"Watchlist\",\n      ...props\n    },\n    reference,\n  ) => {\n    if (items.length === 0) {\n      return null;\n    }\n\n    const advancing = items.filter((item) => item.change >= 0).length;\n    const declining = items.length - advancing;\n\n    return (\n      <section\n        aria-label={title}\n        className={cn(\n          \"rounded-2xl border border-border bg-card/80 p-4 shadow-sm\",\n          className,\n        )}\n        ref={reference}\n        {...props}\n      >\n        <header className=\"mb-3 flex flex-wrap items-start justify-between gap-3\">\n          <div>\n            <p className=\"text-xs font-medium uppercase tracking-[0.28em] text-muted-foreground\">\n              {eyebrow}\n            </p>\n            <h2 className=\"text-lg font-semibold text-foreground\">{title}</h2>\n          </div>\n          <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n            <span className=\"inline-flex items-center gap-1 rounded-full border border-emerald-500/30 bg-emerald-500/10 px-2 py-1 text-emerald-600 dark:text-emerald-400\">\n              <ArrowUpRight className=\"size-3\" />\n              {advancing} up\n            </span>\n            <span className=\"inline-flex items-center gap-1 rounded-full border border-rose-500/30 bg-rose-500/10 px-2 py-1 text-rose-600 dark:text-rose-400\">\n              <ArrowDownRight className=\"size-3\" />\n              {declining} down\n            </span>\n          </div>\n        </header>\n        <ul className=\"divide-y divide-border/60\">\n          {items.map((item) => (\n            <WatchlistRow item={item} key={item.symbol} />\n          ))}\n        </ul>\n      </section>\n    );\n  },\n);\n\nWatchlist.displayName = \"Watchlist\";\n",
      "type": "registry:component"
    }
  ],
  "version": "0.2.1",
  "stability": "stable"
}
