{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "author": "Lopifi (https://lopifi.com)",
  "categories": [
    "swaps-fx",
    "finance",
    "accounting"
  ],
  "dependencies": [],
  "description": "Live multi-pair ticker with value flash.",
  "files": [
    {
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { useLiveTicker, useValueFlash } from \"@/hooks/ledger/use-live-value\";\nimport { cn } from \"@/lib/ledger/cn\";\nimport { formatRate } from \"@/lib/ledger/format-money\";\n\nexport type Pair = { from: string; to: string; rate: number };\n\nexport interface RateTickerProps {\n  className?: string;\n  pairs: Pair[];\n}\n\n/**\n * The value flash is the whole point. Never a marquee — a scrolling ticker\n * is continuous large-surface motion that can't be read and can't be paused.\n * Pauses off-screen and on tab hide.\n */\nexport function RateTicker({ pairs: initial, className }: RateTickerProps) {\n  const [pairs, setPairs] = React.useState(initial);\n  const ref = useLiveTicker(() => {\n    setPairs((prev) =>\n      prev.map((p) => ({\n        ...p,\n        rate: p.rate * (1 + (Math.random() - 0.5) * 0.0018),\n      })),\n    );\n  }, 2400);\n\n  return (\n    <section\n      aria-label=\"Live exchange rates\"\n      className={cn(\n        \"flex flex-wrap gap-x-6 gap-y-2 rounded-md border border-border bg-surface px-4 py-3\",\n        className,\n      )}\n      ref={ref}\n    >\n      {pairs.map((p) => (\n        <TickerCell key={`${p.from}/${p.to}`} pair={p} />\n      ))}\n    </section>\n  );\n}\n\nfunction TickerCell({ pair }: { pair: Pair }) {\n  // Throttled to one flash per 400ms by the tick interval itself.\n  const { flash, key } = useValueFlash(pair.rate);\n  return (\n    <span className=\"flex items-baseline gap-2\">\n      <span className=\"text-caption text-text-secondary\">\n        {pair.from}/{pair.to}\n      </span>\n      <span\n        className={cn(\n          \"numeric rounded-xs px-1 text-figure-sm\",\n          flash === \"positive\" && \"ledger-flash-positive\",\n          flash === \"negative\" && \"ledger-flash-negative\",\n        )}\n        key={key}\n      >\n        {formatRate(pair.rate)}\n      </span>\n    </span>\n  );\n}\n",
      "path": "components/ledger/rate-ticker.tsx",
      "target": "components/ledger/rate-ticker.tsx",
      "type": "registry:component"
    }
  ],
  "name": "rate-ticker",
  "registryDependencies": [
    "@lopifi/theme",
    "@lopifi/cn",
    "@lopifi/format-money",
    "@lopifi/use-live-value"
  ],
  "title": "RateTicker",
  "type": "registry:component"
}
