{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "keyboard",
  "type": "registry:ui",
  "title": "Keyboard",
  "description": "Interactive keyboard component with customizable key styling and a beautifully minimal interface.",
  "author": "Ahdeetai <https://aditya.is-cool.dev>",
  "registryDependencies": [],
  "dependencies": ["lucide-react", "clsx", "tailwind-merge"],
  "files": [
    {
      "type": "registry:ui",
      "path": "components/ui/keyboard.tsx",
      "content": "import {\n  SunDim,\n  Sun,\n  Table,\n  Search,\n  Mic,\n  Moon,\n  Rewind,\n  SkipForward,\n  FastForward,\n  Volume2,\n  Volume1,\n  VolumeX,\n  Globe,\n  ChevronUp,\n  Command,\n  ChevronDown,\n  ChevronLeft,\n  ChevronRight,\n} from 'lucide-react';\nimport { cn } from '@/lib/utils';\n\ninterface KeyboardProps {\n  className?: string;\n  containerClassName?: string;\n  showWASD?: boolean;\n  wasdColorClassName?: string;\n  wasdKeyShadowClassName?: string;\n  textClassName?: string;\n  keyShadowClassName?: string;\n}\n\ninterface KeyProps {\n  label?: string;\n  secondaryLabel?: string;\n  width?: string;\n  height?: string;\n  shadowColor?: string;\n  keyShadowClassName?: string;\n  content?: React.ReactNode;\n  className?: string;\n  icon?: React.ReactNode;\n  textClassName?: string;\n}\n\nconst Key = ({\n  label,\n  secondaryLabel,\n  width = 'w-6',\n  height = 'h-6',\n  shadowColor,\n  keyShadowClassName,\n  content,\n  className = '',\n  icon,\n  textClassName,\n}: KeyProps) => {\n  return (\n    <div\n      className={cn(\n        'p-[0.5px] rounded-[4px] bg-black/20 dark:bg-white/20 shadow-md hover:shadow-none hover:scale-[0.98] cursor-pointer transition duration-100',\n        shadowColor ||\n          keyShadowClassName ||\n          'shadow-black/50 dark:shadow-white/50',\n        className,\n      )}\n    >\n      <div\n        className={cn(\n          height,\n          width,\n          'bg-white dark:bg-[#0A090D] rounded-[3.5px] flex items-center justify-center',\n          'shadow-[inset_0_-0.5px_2px_0_rgba(240,240,240,1),inset_-0.5px_0_2px_0_rgba(240,240,240,1)]',\n          'dark:shadow-[inset_0_-0.5px_2px_0_rgba(13,13,15,1),inset_-0.5px_0_2px_0_rgba(13,13,15,1)]',\n        )}\n      >\n        {content || (\n          <div\n            className={cn(\n              'text-[5px] w-full flex justify-center items-center flex-col h-full leading-none gap-[0.38rem] text-foreground',\n              textClassName,\n            )}\n          >\n            {icon && <span className='block'>{icon}</span>}\n            {secondaryLabel && <span className='block'>{secondaryLabel}</span>}\n            {label && <span className='block'>{label}</span>}\n          </div>\n        )}\n      </div>\n    </div>\n  );\n};\n\nconst ModifierKey = ({\n  label,\n  width,\n  align = 'center',\n  icon,\n  textClassName,\n  keyShadowClassName,\n}: {\n  label: string;\n  width: string;\n  align?: 'start' | 'end' | 'center';\n  icon?: React.ReactNode;\n  textClassName?: string;\n  keyShadowClassName?: string;\n}) => {\n  const alignClasses = {\n    start: 'items-start pl-1',\n    end: 'items-end pr-1',\n    center: 'items-center',\n  };\n\n  return (\n    <Key\n      width={width}\n      keyShadowClassName={keyShadowClassName}\n      content={\n        <div\n          className={cn(\n            'text-[5px] w-full flex justify-center flex-col pb-0.5 text-foreground',\n            alignClasses[align],\n            textClassName,\n          )}\n        >\n          {icon && <span className='block mb-0.5'>{icon}</span>}\n          {label}\n        </div>\n      }\n    />\n  );\n};\n\nconst DualLabelKey = ({\n  main,\n  sub,\n  shadowColor,\n  textClassName,\n  keyShadowClassName,\n}: {\n  main: string;\n  sub: string;\n  shadowColor?: string;\n  textClassName?: string;\n  keyShadowClassName?: string;\n}) => {\n  return (\n    <Key\n      label={main}\n      secondaryLabel={sub}\n      shadowColor={shadowColor}\n      textClassName={textClassName}\n      keyShadowClassName={keyShadowClassName}\n    />\n  );\n};\n\nconst FunctionKey = ({\n  label,\n  icon,\n  textClassName,\n  keyShadowClassName,\n}: {\n  label: string;\n  icon: React.ReactNode;\n  textClassName?: string;\n  keyShadowClassName?: string;\n}) => {\n  return (\n    <Key\n      keyShadowClassName={keyShadowClassName}\n      content={\n        <div\n          className={cn(\n            'text-[5px] w-full flex justify-center items-center flex-col h-full leading-none gap-[0.38rem] text-foreground',\n            textClassName,\n          )}\n        >\n          <span className='block'>{icon}</span>\n          <span className='block'>{label}</span>\n        </div>\n      }\n    />\n  );\n};\n\nconst CommandKey = ({\n  textClassName,\n  keyShadowClassName,\n}: {\n  textClassName?: string;\n  keyShadowClassName?: string;\n}) => {\n  return (\n    <Key\n      width='w-8'\n      keyShadowClassName={keyShadowClassName}\n      content={\n        <div\n          className={cn(\n            'text-[5px] w-full flex items-center flex-col h-full justify-between py-1 text-foreground',\n            textClassName,\n          )}\n        >\n          <div className='flex justify-end w-full pr-1'>\n            <Command className='h-1.5 w-1.5' />\n          </div>\n          <div className='flex justify-start w-full pl-1'>\n            <span className='block'>command</span>\n          </div>\n        </div>\n      }\n    />\n  );\n};\n\nconst ArrowKey = ({\n  direction,\n  className,\n  textClassName,\n  keyShadowClassName,\n}: {\n  direction: 'up' | 'down' | 'left' | 'right';\n  className?: string;\n  textClassName?: string;\n  keyShadowClassName?: string;\n}) => {\n  const icons = {\n    up: <ChevronUp className='h-1.5 w-1.5' />,\n    down: <ChevronDown className='h-1.5 w-1.5' />,\n    left: <ChevronLeft className='h-1.5 w-1.5' />,\n    right: <ChevronRight className='h-1.5 w-1.5' />,\n  };\n\n  return (\n    <div\n      className={cn(\n        'p-[0.5px] rounded-[4px] bg-black/20 dark:bg-white/20 shadow-md hover:shadow-none hover:scale-[0.98] cursor-pointer transition duration-100',\n        keyShadowClassName || 'shadow-black/50 dark:shadow-white/50',\n      )}\n    >\n      <div\n        className={cn(\n          'bg-white dark:bg-[#0A090D] rounded-[3.5px] flex items-center justify-center w-6 h-3',\n          'shadow-[inset_0_-0.5px_2px_0_rgba(240,240,240,1),inset_-0.5px_0_2px_0_rgba(240,240,240,1)]',\n          'dark:shadow-[inset_0_-0.5px_2px_0_rgba(13,13,15,1),inset_-0.5px_0_2px_0_rgba(13,13,15,1)]',\n          className,\n        )}\n      >\n        <div\n          className={cn(\n            'text-[5px] w-full flex justify-center items-center flex-col text-foreground',\n            textClassName,\n          )}\n        >\n          {icons[direction]}\n        </div>\n      </div>\n    </div>\n  );\n};\n\nconst OptionKey = ({ className }: { className?: string }) => {\n  return (\n    <svg\n      fill='none'\n      version='1.1'\n      xmlns='http://www.w3.org/2000/svg'\n      viewBox='0 0 32 32'\n      className={className}\n    >\n      <rect\n        stroke='currentColor'\n        strokeWidth={2}\n        x='18'\n        y='5'\n        width='10'\n        height='2'\n      />\n      <polygon\n        stroke='currentColor'\n        strokeWidth={2}\n        points='10.6,5 4,5 4,7 9.4,7 18.4,27 28,27 28,25 19.6,25'\n      />\n    </svg>\n  );\n};\n\nconst Keyboard = ({\n  className,\n  containerClassName,\n  showWASD = false,\n  wasdColorClassName,\n  wasdKeyShadowClassName,\n  textClassName,\n  keyShadowClassName,\n}: KeyboardProps) => {\n  const functionKeys = [\n    { label: 'F1', icon: <SunDim className='h-1.5 w-1.5' /> },\n    { label: 'F2', icon: <Sun className='h-1.5 w-1.5' /> },\n    { label: 'F3', icon: <Table className='h-1.5 w-1.5' /> },\n    { label: 'F4', icon: <Search className='h-1.5 w-1.5' /> },\n    { label: 'F5', icon: <Mic className='h-1.5 w-1.5' /> },\n    { label: 'F6', icon: <Moon className='h-1.5 w-1.5' /> },\n    { label: 'F7', icon: <Rewind className='h-1.5 w-1.5' /> },\n    { label: 'F8', icon: <SkipForward className='h-1.5 w-1.5' /> },\n    { label: 'F9', icon: <FastForward className='h-1.5 w-1.5' /> },\n    { label: 'F10', icon: <VolumeX className='h-1.5 w-1.5' /> },\n    { label: 'F11', icon: <Volume1 className='h-1.5 w-1.5' /> },\n    { label: 'F12', icon: <Volume2 className='h-1.5 w-1.5' /> },\n  ];\n\n  const numberRow = [\n    { main: '`', sub: '~' },\n    { main: '1', sub: '!' },\n    { main: '2', sub: '@' },\n    { main: '3', sub: '#' },\n    { main: '4', sub: '$' },\n    { main: '5', sub: '%' },\n    { main: '6', sub: '^' },\n    { main: '7', sub: '&' },\n    { main: '8', sub: '*' },\n    { main: '9', sub: '(' },\n    { main: '0', sub: ')' },\n    { main: '-', sub: '_' },\n    { main: '=', sub: '+' },\n  ];\n\n  const qwertyRow = ['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'];\n  const qwertySpecial = [\n    { main: '[', sub: '{' },\n    { main: ']', sub: '}' },\n    { main: '\\\\', sub: '|' },\n  ];\n\n  const asdfRow = ['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L'];\n  const asdfSpecial = [\n    { main: ';', sub: ':' },\n    { main: \"'\", sub: '\"' },\n  ];\n\n  const zxcvRow = ['Z', 'X', 'C', 'V', 'B', 'N', 'M'];\n  const zxcvSpecial = [\n    { main: ',', sub: '<' },\n    { main: '.', sub: '>' },\n    { main: '/', sub: '?' },\n  ];\n\n  return (\n    <div\n      className={cn(\n        'bg-background select-none flex items-center justify-center p-4',\n        containerClassName,\n      )}\n    >\n      <div\n        className={cn(\n          'rounded-md bg-neutral-200 dark:bg-zinc-800 p-1 scale-[0.8] sm:scale-100 md:scale-125 lg:scale-150 w-fit h-fit mx-auto',\n          className,\n        )}\n      >\n        <div className='flex gap-0.5 mb-0.5 w-full shrink-0'>\n          <ModifierKey\n            label='esc'\n            width='w-10'\n            align='start'\n            textClassName={textClassName}\n            keyShadowClassName={keyShadowClassName}\n          />\n\n          {functionKeys.map((key) => (\n            <FunctionKey\n              key={key.label}\n              label={key.label}\n              icon={key.icon}\n              textClassName={textClassName}\n              keyShadowClassName={keyShadowClassName}\n            />\n          ))}\n\n          <Key\n            keyShadowClassName={keyShadowClassName}\n            content={\n              <div className='text-[5px] w-full flex justify-center items-center flex-col text-foreground'>\n                <div className='h-4 w-4 rounded-full bg-linear-to-b from-20% from-neutral-300 dark:from-neutral-900 via-neutral-200 dark:via-black via-50% to-neutral-300 dark:to-neutral-900 to-95% p-px'>\n                  <div className='bg-neutral-100 dark:bg-black h-full w-full rounded-full'></div>\n                </div>\n              </div>\n            }\n          />\n        </div>\n\n        <div className='flex gap-0.5 mb-0.5 w-full shrink-0'>\n          {numberRow.map((key, idx) => (\n            <DualLabelKey\n              key={idx}\n              main={key.main}\n              sub={key.sub}\n              textClassName={textClassName}\n              keyShadowClassName={keyShadowClassName}\n            />\n          ))}\n          <ModifierKey\n            label='delete'\n            width='w-10'\n            align='end'\n            textClassName={textClassName}\n            keyShadowClassName={keyShadowClassName}\n          />\n        </div>\n\n        <div className='flex gap-0.5 mb-0.5 w-full shrink-0'>\n          <ModifierKey\n            label='tab'\n            width='w-10'\n            align='start'\n            textClassName={textClassName}\n            keyShadowClassName={keyShadowClassName}\n          />\n\n          {qwertyRow.map((letter) => (\n            <Key\n              key={letter}\n              label={letter}\n              shadowColor={\n                showWASD && letter === 'W' ? wasdKeyShadowClassName : undefined\n              }\n              keyShadowClassName={keyShadowClassName}\n              textClassName={\n                showWASD && letter === 'W'\n                  ? cn(textClassName, wasdColorClassName)\n                  : textClassName\n              }\n            />\n          ))}\n\n          {qwertySpecial.map((key, idx) => (\n            <DualLabelKey\n              key={idx}\n              main={key.main}\n              sub={key.sub}\n              textClassName={textClassName}\n              keyShadowClassName={keyShadowClassName}\n            />\n          ))}\n        </div>\n\n        <div className='flex gap-0.5 mb-0.5 w-full shrink-0'>\n          <ModifierKey\n            label='caps lock'\n            width='w-[2.8rem]'\n            align='start'\n            textClassName={textClassName}\n            keyShadowClassName={keyShadowClassName}\n          />\n\n          {asdfRow.map((letter) => (\n            <Key\n              key={letter}\n              label={letter}\n              shadowColor={\n                showWASD && ['A', 'S', 'D'].includes(letter)\n                  ? wasdKeyShadowClassName\n                  : undefined\n              }\n              keyShadowClassName={keyShadowClassName}\n              textClassName={\n                showWASD && ['A', 'S', 'D'].includes(letter)\n                  ? cn(textClassName, wasdColorClassName)\n                  : textClassName\n              }\n            />\n          ))}\n\n          {asdfSpecial.map((key, idx) => (\n            <DualLabelKey\n              key={idx}\n              main={key.main}\n              sub={key.sub}\n              textClassName={textClassName}\n              keyShadowClassName={keyShadowClassName}\n            />\n          ))}\n\n          <ModifierKey\n            label='return'\n            width='w-[2.85rem]'\n            align='end'\n            textClassName={textClassName}\n            keyShadowClassName={keyShadowClassName}\n          />\n        </div>\n\n        <div className='flex gap-0.5 mb-0.5 w-full shrink-0'>\n          <ModifierKey\n            label='shift'\n            width='w-[3.65rem]'\n            textClassName={textClassName}\n            keyShadowClassName={keyShadowClassName}\n          />\n\n          {zxcvRow.map((letter) => (\n            <Key\n              key={letter}\n              label={letter}\n              textClassName={textClassName}\n              keyShadowClassName={keyShadowClassName}\n            />\n          ))}\n\n          {zxcvSpecial.map((key, idx) => (\n            <DualLabelKey\n              key={idx}\n              main={key.main}\n              sub={key.sub}\n              textClassName={textClassName}\n              keyShadowClassName={keyShadowClassName}\n            />\n          ))}\n\n          <ModifierKey\n            label='shift'\n            width='w-[3.65rem]'\n            textClassName={textClassName}\n            keyShadowClassName={keyShadowClassName}\n          />\n        </div>\n\n        <div className='flex gap-0.5 mb-0.5 w-full shrink-0'>\n          <Key\n            height='h-7'\n            width='w-7'\n            keyShadowClassName={keyShadowClassName}\n            content={\n              <div\n                className={cn(\n                  'text-[5px] w-full flex items-center flex-col h-full justify-between py-1 text-foreground',\n                  textClassName,\n                )}\n              >\n                <div className='flex justify-start w-full pl-1'>\n                  <Globe className='h-1.25 w-1.25' />\n                </div>\n                <div className='flex justify-center w-full pr-1'>\n                  <span className='block'>fn</span>\n                </div>\n              </div>\n            }\n          />\n\n          <Key\n            width='w-6'\n            height='h-6'\n            keyShadowClassName={keyShadowClassName}\n            content={\n              <div\n                className={cn(\n                  'text-[5px] w-full flex items-center flex-col h-full justify-between py-1 text-foreground',\n                  textClassName,\n                )}\n              >\n                <div className='flex justify-end w-full pr-1'>\n                  <ChevronUp className='h-1.5 w-1.5' />\n                </div>\n                <div className='flex justify-start w-full pl-1'>\n                  <span className='block'>control</span>\n                </div>\n              </div>\n            }\n          />\n\n          <Key\n            width='w-6'\n            height='h-6'\n            keyShadowClassName={keyShadowClassName}\n            content={\n              <div\n                className={cn(\n                  'text-[5px] w-full flex items-center flex-col h-full justify-between py-1 text-foreground',\n                  textClassName,\n                )}\n              >\n                <div className='flex justify-end w-full pr-1'>\n                  <OptionKey className='h-1.5 w-1.5' />\n                </div>\n                <div className='flex justify-start w-full pl-1'>\n                  <span className='block'>option</span>\n                </div>\n              </div>\n            }\n          />\n\n          <CommandKey\n            textClassName={textClassName}\n            keyShadowClassName={keyShadowClassName}\n          />\n\n          <Key\n            width='w-[8.2rem]'\n            keyShadowClassName={keyShadowClassName}\n            content={\n              <div\n                className={cn(\n                  'text-[0.4rem] w-full flex justify-center items-center flex-col text-foreground',\n                  textClassName,\n                )}\n              >\n                <span className='block font-bold'>ScrollX UI</span>\n              </div>\n            }\n          />\n\n          <CommandKey\n            textClassName={textClassName}\n            keyShadowClassName={keyShadowClassName}\n          />\n\n          <Key\n            width='w-6'\n            height='h-6'\n            keyShadowClassName={keyShadowClassName}\n            content={\n              <div\n                className={cn(\n                  'text-[5px] w-full flex items-center flex-col h-full justify-between py-1 text-foreground',\n                  textClassName,\n                )}\n              >\n                <div className='flex justify-end w-full pr-1'>\n                  <OptionKey className='h-1.5 w-1.5' />\n                </div>\n                <div className='flex justify-start w-full pl-1'>\n                  <span className='block'>option</span>\n                </div>\n              </div>\n            }\n          />\n\n          <div className='w-[4.9rem] mt-0.5 h-6 p-[0.5px] rounded-[4px] flex flex-col justify-end items-center'>\n            <ArrowKey\n              direction='up'\n              textClassName={textClassName}\n              keyShadowClassName={keyShadowClassName}\n            />\n            <div className='flex'>\n              <ArrowKey\n                direction='left'\n                textClassName={textClassName}\n                keyShadowClassName={keyShadowClassName}\n              />\n              <ArrowKey\n                direction='down'\n                textClassName={textClassName}\n                keyShadowClassName={keyShadowClassName}\n              />\n              <ArrowKey\n                direction='right'\n                textClassName={textClassName}\n                keyShadowClassName={keyShadowClassName}\n              />\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n};\n\nexport { Keyboard };\n"
    },
    {
      "type": "registry:lib",
      "path": "lib/utils.ts",
      "content": "import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}"
    }
  ]
}
