{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "list-stack",
  "type": "registry:component",
  "title": "List Stack",
  "description": "An animated stacked list that smoothly expands and collapses to reveal or hide items.",
  "dependencies": [
    "motion",
    "react-icons"
  ],
  "files": [
    {
      "path": "components/watermelon/list-stack.tsx",
      "type": "registry:component",
      "content": "'use client';\n\nimport { useState, type FC } from 'react';\nimport { motion, AnimatePresence } from 'motion/react';\n\nimport { FaFireFlameCurved, FaSailboat } from 'react-icons/fa6';\nimport { LuTent } from 'react-icons/lu';\nimport { type IconType } from 'react-icons';\n\ninterface ListItem {\n  id: string;\n  title: string;\n  location: string;\n  date: string;\n  icon: IconType;\n}\n\ninterface ListStackProps {\n  items?: ListItem[];\n}\n\nconst ITEMS: ListItem[] = [\n  {\n    id: '1',\n    title: 'Camping',\n    location: 'Yosemite Park',\n    date: '5 August',\n    icon: LuTent,\n  },\n  {\n    id: '2',\n    title: 'Boating',\n    location: 'Lake Tahoe Park',\n    date: '2 August',\n    icon: FaSailboat,\n  },\n  {\n    id: '3',\n    title: 'Barbecue',\n    location: 'Greenfield Shores',\n    date: '28 July',\n    icon: FaFireFlameCurved,\n  },\n];\nconst CARD_HEIGHT = 60;\nconst GAP = 8;\nconst COLLAPSED_OFFSET = -7;\n\nexport const ListStack: FC<ListStackProps> = ({ items = ITEMS }) => {\n  const [isExpanded, setIsExpanded] = useState(false);\n\n  return (\n    <div className=\"h- w-full font-sans\">\n      <div className=\"flex h-[400px] w-full flex-col items-center justify-center\">\n        <div className=\"relative flex h-full w-full flex-col items-center justify-center perspective-[1000px]\">\n          {items.map((item, i) => {\n            return (\n              <motion.div\n                className=\"bg-opacity-80 absolute flex w-[270px] items-center rounded-2xl bg-white px-3 py-3 shadow-[0px_0px_2px_rgba(0,0,0,0.1),0px_1px_4px_rgba(0,0,0,0.15)] backdrop-blur-2xl dark:border-gray-100 dark:bg-zinc-800\"\n                key={i}\n                animate={isExpanded ? 'expanded' : 'collapsed'}\n                style={{\n                  height: CARD_HEIGHT,\n                }}\n                variants={{\n                  expanded: {\n                    y: (items.length - 1 - i) * (CARD_HEIGHT + GAP),\n                    z: 10,\n                  },\n                  collapsed: {\n                    y: i * COLLAPSED_OFFSET,\n                    z: i * 60,\n                  },\n                }}\n                transition={{\n                  type: 'spring',\n                  stiffness: 200,\n                  damping: 23,\n                }}\n              >\n                <div className=\"flex w-full items-center font-sans\">\n                  <div\n                    key={i}\n                    className=\"flex w-full items-center gap-x-2 text-neutral-900\"\n                  >\n                    <div className=\"flex size-10 items-center justify-center rounded-md bg-black text-zinc-100 dark:bg-white dark:text-zinc-700\">\n                      <item.icon size={24} />\n                    </div>\n                    <div className=\"leading-tighter flex-1\">\n                      <h3 className=\"text-sm text-zinc-900 dark:text-zinc-100\">\n                        {item.title}\n                      </h3>\n                      <p className=\"text-xs text-zinc-500 dark:text-zinc-400\">\n                        {item.location}\n                      </p>\n                    </div>\n\n                    <span className=\"leading-tighter mb-[2px] ml-5 self-end text-end text-xs text-zinc-500 dark:text-zinc-400\">\n                      {item.date}\n                    </span>\n                  </div>\n                </div>\n              </motion.div>\n            );\n          })}\n          <motion.div\n            className=\"absolute cursor-pointer rounded-2xl border border-gray-100 bg-white px-4 py-2 text-neutral-900 shadow-sm\"\n            animate={{\n              y: isExpanded\n                ? (items.length - 1) * (CARD_HEIGHT + GAP) + CARD_HEIGHT + GAP\n                : CARD_HEIGHT + GAP,\n              z: isExpanded ? 0 : 40,\n            }}\n            transition={{\n              type: 'spring',\n              stiffness: 200,\n              damping: 25,\n            }}\n            layout\n            onClick={() => {\n              setIsExpanded((prev) => !prev);\n            }}\n          >\n            <AnimatePresence mode=\"popLayout\">\n              <motion.span\n                layout\n                key={isExpanded ? 'hide' : 'show'}\n                initial={{\n                  opacity: 0,\n                }}\n                animate={{\n                  opacity: 1,\n                }}\n                exit={{\n                  opacity: 0,\n                }}\n                transition={{\n                  duration: 0.2,\n                }}\n              >\n                {' '}\n                {isExpanded ? 'Hide ' : 'Show '}\n              </motion.span>\n            </AnimatePresence>\n          </motion.div>\n        </div>\n      </div>\n    </div>\n  );\n};\n"
    }
  ]
}
