{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "ink/clock",
  "title": "Clock",
  "description": "Real-time clock display with 12h/24h and date",
  "dependencies": [
    "ink"
  ],
  "registryDependencies": [
    "https://termcn.dev/r/ink/terminal-symbols.json",
    "https://termcn.dev/r/ink/use-interval.json",
    "https://termcn.dev/r/ink/use-theme.json",
    "https://termcn.dev/r/ink/use-unicode.json"
  ],
  "files": [
    {
      "path": "registry/ui/clock.tsx",
      "content": "import { Box, Text } from \"ink\";\nimport React, { useState, useCallback } from \"react\";\n\nimport { useInterval } from \"@/hooks/use-interval\";\nimport { useTheme } from \"@/hooks/use-theme\";\nimport { useUnicode } from \"@/hooks/use-unicode\";\nimport { toAsciiComponentText } from \"@/lib/terminal-symbols\";\n\nexport interface ClockProps {\n  format?: \"12h\" | \"24h\";\n  showSeconds?: boolean;\n  showDate?: boolean;\n  timezone?: string;\n  color?: string;\n  size?: \"sm\" | \"lg\";\n  isActive?: boolean;\n  \"aria-label\"?: string;\n}\n\nconst BIG_DIGITS: Record<string, string[]> = {\n  \" \": [\"   \", \"   \", \"   \", \"   \", \"   \"],\n  \"0\": [\"╔═╗\", \"║ ║\", \"║ ║\", \"║ ║\", \"╚═╝\"],\n  \"1\": [\" ╗ \", \" ║ \", \" ║ \", \" ║ \", \" ╩ \"],\n  \"2\": [\"╔═╗\", \"  ║\", \"╔═╝\", \"║  \", \"╚══\"],\n  \"3\": [\"╔═╗\", \"  ║\", \" ═╣\", \"  ║\", \"╚═╝\"],\n  \"4\": [\"╗ ╗\", \"║ ║\", \"╚═╣\", \"  ║\", \"  ╩\"],\n  \"5\": [\"╔══\", \"║  \", \"╚═╗\", \"  ║\", \"╚═╝\"],\n  \"6\": [\"╔══\", \"║  \", \"╠═╗\", \"║ ║\", \"╚═╝\"],\n  \"7\": [\"╔═╗\", \"  ║\", \"  ║\", \"  ║\", \"  ╩\"],\n  \"8\": [\"╔═╗\", \"║ ║\", \"╠═╣\", \"║ ║\", \"╚═╝\"],\n  \"9\": [\"╔═╗\", \"║ ║\", \"╚═╣\", \"  ║\", \"╚═╝\"],\n  \":\": [\"   \", \" ● \", \"   \", \" ● \", \"   \"],\n};\n\nconst renderBigText = (\n  str: string,\n  color: string,\n  unicode: boolean\n): React.ReactElement => {\n  const rows: string[] = [\"\", \"\", \"\", \"\"];\n  for (const ch of str) {\n    const segs = BIG_DIGITS[ch] ?? BIG_DIGITS[\" \"] ?? [];\n    for (let r = 0; r < 5; r += 1) {\n      rows[r] += segs[r];\n    }\n  }\n  return (\n    <Box flexDirection=\"column\">\n      {rows.map((row, i) => (\n        <Text key={i} color={color}>\n          {unicode ? row : toAsciiComponentText(row)}\n        </Text>\n      ))}\n    </Box>\n  );\n};\n\nconst padNum = (n: number) => String(n).padStart(2, \"0\");\n\nconst getTimeParts = (\n  format: \"12h\" | \"24h\",\n  showSeconds: boolean,\n  timezone?: string\n) => {\n  const now = timezone\n    ? new Date(new Date().toLocaleString(\"en-US\", { timeZone: timezone }))\n    : new Date();\n\n  let hours = now.getHours();\n  const minutes = now.getMinutes();\n  const seconds = now.getSeconds();\n  let ampm = \"\";\n\n  if (format === \"12h\") {\n    ampm = hours >= 12 ? \" PM\" : \" AM\";\n    hours = hours % 12 || 12;\n  }\n\n  const time = showSeconds\n    ? `${padNum(hours)}:${padNum(minutes)}:${padNum(seconds)}`\n    : `${padNum(hours)}:${padNum(minutes)}`;\n\n  return { ampm, time };\n};\n\nconst getDateString = (timezone?: string): string => {\n  const now = timezone\n    ? new Date(new Date().toLocaleString(\"en-US\", { timeZone: timezone }))\n    : new Date();\n  return now.toLocaleDateString(\"en-US\", {\n    day: \"numeric\",\n    month: \"short\",\n    weekday: \"short\",\n    year: \"numeric\",\n  });\n};\n\nexport const Clock = ({\n  format = \"24h\",\n  showSeconds = true,\n  showDate = false,\n  timezone,\n  color,\n  size = \"sm\",\n  isActive = true,\n  \"aria-label\": ariaLabel,\n}: ClockProps) => {\n  const theme = useTheme();\n  const unicode = useUnicode();\n  const resolvedColor = color ?? theme.colors.primary;\n\n  const [_tick, setTick] = useState(0);\n  useInterval(\n    useCallback(() => setTick((t) => t + 1), []),\n    1000,\n    { isActive }\n  );\n\n  const { time, ampm } = getTimeParts(format, showSeconds, timezone);\n\n  if (size === \"lg\") {\n    return (\n      <Box\n        flexDirection=\"column\"\n        gap={0}\n        aria-role=\"timer\"\n        aria-label={\n          ariaLabel ??\n          `Clock: ${time}${ampm}${showDate ? `. ${getDateString(timezone)}` : \"\"}`\n        }\n      >\n        {showDate && (\n          <Text color={theme.colors.mutedForeground}>\n            {getDateString(timezone)}\n          </Text>\n        )}\n        <Box alignItems=\"flex-end\" gap={0}>\n          {renderBigText(time, resolvedColor, unicode)}\n          {ampm && (\n            <Text color={theme.colors.mutedForeground} bold>\n              {ampm}\n            </Text>\n          )}\n        </Box>\n      </Box>\n    );\n  }\n\n  return (\n    <Box\n      flexDirection=\"column\"\n      gap={0}\n      aria-role=\"timer\"\n      aria-label={\n        ariaLabel ??\n        `Clock: ${time}${ampm}${showDate ? `. ${getDateString(timezone)}` : \"\"}`\n      }\n    >\n      {showDate && (\n        <Text color={theme.colors.mutedForeground}>\n          {getDateString(timezone)}\n        </Text>\n      )}\n      <Box gap={0}>\n        <Text color={resolvedColor} bold>\n          {time}\n        </Text>\n        {ampm && <Text color={theme.colors.mutedForeground}>{ampm}</Text>}\n      </Box>\n    </Box>\n  );\n};\n",
      "type": "registry:ui"
    }
  ],
  "categories": [
    "utility"
  ],
  "type": "registry:ui"
}