{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "inline-edit",
  "type": "registry:component",
  "title": "Inline Edit",
  "description": "A sleek, interactive editor that transitions seamlessly between display and edit modes using smooth layout animations.",
  "dependencies": [
    "@hugeicons/core-free-icons",
    "@hugeicons/react",
    "motion"
  ],
  "files": [
    {
      "path": "components/watermelon/inline-edit.tsx",
      "type": "registry:component",
      "content": "'use client';\n\nimport { useState, useId, type FC } from 'react';\nimport { motion, AnimatePresence, type Transition } from 'motion/react';\nimport { HugeiconsIcon } from '@hugeicons/react';\nimport {\n  AlarmClockFreeIcons,\n  Calendar03Icon,\n  Cancel01Icon,\n  Edit03Icon,\n  Link01Icon,\n  Menu02Icon,\n  Tick02Icon,\n  Ticket02Icon,\n} from '@hugeicons/core-free-icons/index';\n\ninterface EditableRowProps {\n  icon: any;\n  label: string;\n  value: string;\n  secondaryValue?: string;\n  onSave?: (value: string) => void;\n  onSaveRange?: (v1: string, v2: string) => void;\n  type?: 'text' | 'time' | 'url';\n  multiline?: boolean;\n}\n\nexport interface EventData {\n  event: string;\n  date: string;\n  start: string;\n  end: string;\n  location: string;\n  url: string;\n  desc: string;\n}\n\ninterface InlineEditCardProps {\n  data: EventData;\n  onDataChange: (data: EventData) => void;\n  title?: string;\n}\n\nconst spring: Transition = {\n  type: 'spring',\n  stiffness: 420,\n  damping: 28,\n  mass: 0.6,\n};\n\nconst EditableRow: FC<EditableRowProps> = ({\n  icon,\n  label,\n  value,\n  secondaryValue,\n  onSave,\n  onSaveRange,\n  type = 'text',\n  multiline = false,\n}) => {\n  const [editing, setEditing] = useState(false);\n  const [v1, setV1] = useState(value);\n  const [v2, setV2] = useState(secondaryValue || '');\n  const inputId = useId();\n  const secondaryInputId = useId();\n  const isTime = type === 'time';\n\n  const handleSave = () => {\n    if (isTime && onSaveRange) onSaveRange(v1, v2);\n    else if (onSave) onSave(v1);\n    setEditing(false);\n  };\n\n  return (\n    <motion.div\n      layout\n      transition={spring}\n      className={`relative flex w-full ${multiline ? 'flex-col items-start gap-4' : 'flex-col gap-2 sm:flex-row sm:items-center sm:gap-4'}`}\n    >\n      <div\n        className={`flex shrink-0 items-center gap-3 ${multiline ? 'w-full' : 'w-full sm:w-[130px]'}`}\n      >\n        <HugeiconsIcon\n          icon={icon}\n          size={24}\n          color=\"#9ca3af\"\n          strokeWidth={1.5}\n        />\n        <label\n          htmlFor={inputId}\n          className=\"cursor-pointer text-[16px] font-medium text-gray-500 dark:text-gray-400\"\n        >\n          {label}\n        </label>\n      </div>\n\n      <div\n        className={`relative w-full bg-white transition-colors dark:bg-zinc-950`}\n      >\n        <motion.div\n          layout\n          className=\"group/content w-full rounded-xl px-2 hover:bg-gray-50 sm:px-3 dark:hover:bg-zinc-900/50\"\n        >\n          <motion.div\n            layout\n            transition={spring}\n            className={`relative flex min-h-[40px] w-full gap-2 overflow-hidden ${multiline ? 'flex-col py-2.5' : 'items-center'}`}\n          >\n            {isTime ? (\n              <div className=\"flex w-full gap-2\">\n                <input\n                  id={inputId}\n                  autoFocus\n                  type=\"text\"\n                  readOnly={!editing}\n                  value={v1}\n                  onChange={(e) => setV1(e.target.value)}\n                  className=\"h-10 w-full rounded-xl border border-transparent bg-transparent text-[16px] leading-relaxed font-medium text-gray-900 outline-none focus:border-gray-200 dark:text-gray-100 dark:focus:border-zinc-800\"\n                />\n                <input\n                  id={secondaryInputId}\n                  type=\"text\"\n                  readOnly={!editing}\n                  value={v2}\n                  onChange={(e) => setV2(e.target.value)}\n                  className=\"h-10 w-full rounded-xl border border-transparent bg-transparent text-[16px] leading-relaxed font-medium text-gray-900 outline-none focus:border-gray-200 dark:text-gray-100 dark:focus:border-zinc-800\"\n                />\n              </div>\n            ) : multiline ? (\n              <textarea\n                id={inputId}\n                autoFocus\n                readOnly={!editing}\n                rows={3}\n                value={v1}\n                onChange={(e) => setV1(e.target.value)}\n                className=\"w-full resize-none rounded-xl bg-transparent px-0 py-0 text-[16px] leading-relaxed font-medium text-gray-900 outline-none dark:text-gray-100\"\n              />\n            ) : (\n              <input\n                id={inputId}\n                autoFocus\n                type=\"text\"\n                readOnly={!editing}\n                value={v1}\n                onChange={(e) => setV1(e.target.value)}\n                onKeyDown={(e) => e.key === 'Enter' && handleSave()}\n                className=\"h-10 w-full rounded-xl bg-transparent text-[15px] font-medium text-gray-900 outline-none sm:text-base dark:text-gray-100\"\n              />\n            )}\n\n            <div className=\"mr-0.5 flex shrink-0 items-center justify-end\">\n              <AnimatePresence mode=\"popLayout\" initial={false}>\n                {editing ? (\n                  <motion.div\n                    key=\"edit\"\n                    className=\"flex gap-1\"\n                    initial={{ opacity: 0, y: 40 }}\n                    animate={{ opacity: 1, y: 0 }}\n                    exit={{ opacity: 0, y: 40 }}\n                    transition={{\n                      duration: 0.4,\n                      ease: [0.19, 1, 0.22, 1],\n                    }}\n                  >\n                    <motion.button\n                      whileHover={{ scale: 1.05 }}\n                      whileTap={{ scale: 0.95 }}\n                      onClick={handleSave}\n                      className=\"flex size-7 items-center justify-center rounded-lg bg-gray-900 text-white dark:bg-gray-100 dark:text-black\"\n                    >\n                      <HugeiconsIcon icon={Tick02Icon} size={18} />\n                    </motion.button>\n\n                    <motion.button\n                      whileHover={{ scale: 1.05 }}\n                      whileTap={{ scale: 0.95 }}\n                      onClick={() => setEditing(false)}\n                      className=\"flex size-7 items-center justify-center rounded-lg bg-gray-900 text-white dark:bg-zinc-800\"\n                    >\n                      <HugeiconsIcon\n                        icon={Cancel01Icon}\n                        size={18}\n                        color=\"#ffffff\"\n                      />\n                    </motion.button>\n                  </motion.div>\n                ) : (\n                  <motion.div\n                    exit={{ opacity: 1 }}\n                    key=\"view\"\n                    className={`flex size-7 items-center justify-center rounded-lg border border-gray-200 bg-white opacity-0 shadow-sm group-hover/content:opacity-100 dark:border-zinc-800 dark:bg-zinc-900 ${multiline ? 'mt-1 self-end' : ''}`}\n                    onClick={() => setEditing(true)}\n                  >\n                    <HugeiconsIcon\n                      icon={Edit03Icon}\n                      size={18}\n                      color=\"#9ca3af\"\n                    />\n                  </motion.div>\n                )}\n              </AnimatePresence>\n            </div>\n          </motion.div>\n        </motion.div>\n      </div>\n    </motion.div>\n  );\n};\n\nexport const InlineEditCard: FC<InlineEditCardProps> = ({\n  data,\n  onDataChange,\n  title = 'Update Details',\n}) => {\n  return (\n    <div className=\"mx-auto h-fit w-[92vw] max-w-xs rounded-[34px] border border-gray-200 bg-gray-50 p-1.5 shadow-sm transition-colors sm:mx-0 sm:w-[440px] sm:max-w-none dark:border-zinc-800 dark:bg-zinc-900\">\n      <div className=\"w-full overflow-hidden rounded-[28px] border border-gray-200 bg-white transition-colors dark:border-zinc-800 dark:bg-zinc-950\">\n        <div className=\"rounded-t-[32px] border-b border-gray-200 bg-gray-50 px-8 py-3.5 dark:border-zinc-800 dark:bg-zinc-900/50\">\n          <h4 className=\"text-[15px] font-semibold tracking-wide text-gray-500 uppercase dark:text-gray-400\">\n            {title}\n          </h4>\n        </div>\n\n        <div className=\"space-y-4 px-4 py-3 sm:space-y-1\">\n          <EditableRow\n            icon={Ticket02Icon}\n            label=\"Event\"\n            value={data.event}\n            onSave={(v) => onDataChange({ ...data, event: v })}\n          />\n          <EditableRow\n            icon={Calendar03Icon}\n            label=\"Date\"\n            value={data.date}\n            onSave={(v) => onDataChange({ ...data, date: v })}\n          />\n          <EditableRow\n            icon={AlarmClockFreeIcons}\n            label=\"Time\"\n            type=\"time\"\n            value={data.start}\n            secondaryValue={data.end}\n            onSaveRange={(a, b) => onDataChange({ ...data, start: a, end: b })}\n          />\n          <EditableRow\n            icon={Link01Icon}\n            label=\"URL\"\n            type=\"url\"\n            value={data.url}\n            onSave={(v) => onDataChange({ ...data, url: v })}\n          />\n          <div className=\"mt-2 border-t border-gray-100 pt-4 dark:border-zinc-900\">\n            <EditableRow\n              icon={Menu02Icon}\n              label=\"Description\"\n              multiline\n              value={data.desc}\n              onSave={(v) => onDataChange({ ...data, desc: v })}\n            />\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n};\n"
    }
  ]
}
