{
  "$schema": "https://www.cooki-ui.design/schema/registry-item.json",
  "name": "animated-floating-input",
  "type": "registry:ui",
  "title": "Animated Floating Input",
  "description": "Material/Vercel-style input with smooth spring floating label, clear action, and validation styling.",
  "category": "forms",
  "dependencies": [
    "framer-motion",
    "@phosphor-icons/react"
  ],
  "files": [
    {
      "path": "registry/forms/animated-floating-input/animated-floating-input.tsx",
      "type": "registry:ui",
      "target": "components/ui/animated-floating-input.tsx",
      "content": "import React, { useState } from 'react';\nimport { motion, AnimatePresence } from 'framer-motion';\nimport { X, CheckCircle, WarningCircle } from '@phosphor-icons/react';\n\nexport interface AnimatedFloatingInputProps {\n  label?: string;\n  type?: string;\n  value?: string;\n  placeholder?: string;\n  error?: string;\n  success?: boolean;\n  onChange?: (val: string) => void;\n  className?: string;\n}\n\nexport const AnimatedFloatingInput: React.FC<AnimatedFloatingInputProps> = ({\n  label = 'Engineering Handle',\n  type = 'text',\n  value: controlledValue,\n  placeholder = '',\n  error,\n  success,\n  onChange,\n  className = '',\n}) => {\n  const [internalValue, setInternalValue] = useState('architect@cooki.dev');\n  const [isFocused, setIsFocused] = useState(false);\n  const value = controlledValue !== undefined ? controlledValue : internalValue;\n  const isFloating = isFocused || value.length > 0;\n\n  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n    setInternalValue(e.target.value);\n    onChange?.(e.target.value);\n  };\n\n  return (\n    <div className={`relative w-full max-w-sm ${className}`}>\n      <div\n        className={`relative rounded-2xl border bg-white dark:bg-zinc-900/60 transition-all duration-200 ${\n          error\n            ? 'border-rose-500/80 ring-2 ring-rose-500/20'\n            : success\n            ? 'border-emerald-500/80 ring-2 ring-emerald-500/20'\n            : isFocused\n            ? 'border-indigo-500 ring-2 ring-indigo-500/20 shadow-lg shadow-indigo-500/10'\n            : 'border-zinc-300 dark:border-white/10 hover:border-zinc-400 dark:hover:border-white/20'\n        }`}\n      >\n        <motion.label\n          initial={false}\n          animate={{\n            top: isFloating ? '8px' : '18px',\n            fontSize: isFloating ? '10px' : '13px',\n            color: error\n              ? '#f43f5e'\n              : isFocused\n              ? '#818cf8'\n              : isFloating\n              ? '#a1a1aa'\n              : '#71717a',\n          }}\n          transition={{ duration: 0.15, ease: 'easeOut' }}\n          className=\"absolute left-4 pointer-events-none font-mono uppercase tracking-wider font-semibold select-none z-10\"\n        >\n          {label}\n        </motion.label>\n\n        <input\n          type={type}\n          value={value}\n          onFocus={() => setIsFocused(true)}\n          onBlur={() => setIsFocused(false)}\n          onChange={handleChange}\n          placeholder={isFocused ? placeholder : ''}\n          className=\"w-full bg-transparent px-4 pt-6 pb-2.5 text-xs text-zinc-900 dark:text-zinc-100 font-mono outline-none\"\n        />\n\n        <div className=\"absolute right-3 top-1/2 -translate-y-1/2 flex items-center gap-1.5\">\n          {value && (\n            <button\n              type=\"button\"\n              onClick={() => {\n                setInternalValue('');\n                onChange?.('');\n              }}\n              className=\"text-zinc-400 hover:text-zinc-600 dark:hover:text-white p-1 rounded-full transition-colors cursor-pointer\"\n            >\n              <X size={12} weight=\"bold\" />\n            </button>\n          )}\n          {success && <CheckCircle size={15} weight=\"fill\" className=\"text-emerald-500\" />}\n          {error && <WarningCircle size={15} weight=\"fill\" className=\"text-rose-500\" />}\n        </div>\n      </div>\n\n      <AnimatePresence>\n        {error && (\n          <motion.p\n            initial={{ opacity: 0, y: -4 }}\n            animate={{ opacity: 1, y: 0 }}\n            exit={{ opacity: 0, y: -4 }}\n            className=\"mt-1.5 ml-2 text-[10px] font-mono text-rose-400\"\n          >\n            {error}\n          </motion.p>\n        )}\n      </AnimatePresence>\n    </div>\n  );\n};\n"
    }
  ]
}