{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "roll-number",
  "title": "Roll Number",
  "description": "Each digit is its own column, so only the digits that change move.",
  "registryDependencies": [
    "https://spotcheckui.com/r/spotcheck-base.json"
  ],
  "files": [
    {
      "path": "registry/spotcheck/components/spotcheck/roll-number.tsx",
      "content": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst DIGITS = \"0123456789\"\nconst DURATION_MS = 900\nconst EASING = \"cubic-bezier(.2,.9,.15,1)\"\n\ntype RollNumberProps = Omit<React.ComponentProps<\"span\">, \"children\"> & {\n  /** A number to format. Ignored when `text` is set. */\n  value?: number\n  /** Preformatted text such as \"₹1,990\". Digits roll, everything else stays still. */\n  text?: string\n  /** The locale used to format `value`. */\n  locale?: string\n  /** Passed to Intl.NumberFormat, for currency or decimal places. */\n  formatOptions?: Intl.NumberFormatOptions\n  /** Roll time in milliseconds. */\n  duration?: number\n}\n\nexport function RollNumber({\n  value = 0,\n  text,\n  locale = \"en-US\",\n  formatOptions,\n  duration = DURATION_MS,\n  className,\n  style,\n  ...props\n}: RollNumberProps) {\n  const label = text ?? new Intl.NumberFormat(locale, formatOptions).format(value)\n  const chars = Array.from(label)\n\n  return (\n    <span\n      className={cn(\"spotcheck-display relative inline-flex tabular-nums\", className)}\n      // Inline, because a text-size class passed in className would make tailwind-merge drop it.\n      style={{ lineHeight: 1, ...style }}\n      {...props}\n    >\n      <span className=\"sr-only\">{label}</span>\n      {chars.map((char, index) => {\n        // Keys count from the right, so units stay in the same column as the number grows.\n        const place = chars.length - index\n        const digit = DIGITS.indexOf(char)\n\n        if (digit === -1) {\n          return (\n            <span key={`static-${place}`} aria-hidden>\n              {char}\n            </span>\n          )\n        }\n\n        return (\n          <span key={`digit-${place}`} aria-hidden className=\"inline-block h-[1em] overflow-hidden\">\n            <span\n              data-digit={digit}\n              className=\"flex flex-col motion-reduce:transition-none\"\n              style={{\n                transform: `translateY(${-digit * 10}%)`,\n                transition: `transform ${duration}ms ${EASING}`,\n              }}\n            >\n              {Array.from(DIGITS, (d) => (\n                <span key={d} className=\"block h-[1em]\">\n                  {d}\n                </span>\n              ))}\n            </span>\n          </span>\n        )\n      })}\n    </span>\n  )\n}\n",
      "type": "registry:component"
    }
  ],
  "categories": [
    "motion"
  ],
  "type": "registry:component"
}