{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "list-item",
  "title": "List Item",
  "description": "Interactive list items with hover and focus effects.",
  "dependencies": [
    "motion",
    "@hugeicons/core-free-icons",
    "@hugeicons/react",
    "clsx",
    "tailwind-merge"
  ],
  "files": [
    {
      "path": "registry/default/example/list-item.tsx",
      "content": "\"use client\";\nimport { motion, MotionConfig } from \"motion/react\";\nimport { Dispatch, SetStateAction, useState } from \"react\";\nimport clsx from \"clsx\";\n\nimport {\n  Appointment01Icon,\n  BalloonsIcon,\n  GoogleMapsIcon,\n  ZoomIcon,\n  ReminderIcon,\n  TaskDaily01Icon,\n  Tick02Icon,\n  FilterHorizontalIcon,\n} from \"@hugeicons/core-free-icons\";\nimport { HugeiconsFreeIcons } from \"@hugeicons/core-free-icons\";\nimport { HugeiconsIcon } from \"@hugeicons/react\";\n\nexport type FilterKey = (typeof filterKeys)[number];\n\n// Change Here\nexport const filterKeys = [\n  {\n    name: \"tasks\",\n    Icon: ({ size }: { size: number }) => (\n      <HugeiconsIcon icon={TaskDaily01Icon} size={size} />\n    ),\n  },\n  {\n    name: \"events\",\n    Icon: ({ size }: { size: number }) => (\n      <HugeiconsIcon icon={GoogleMapsIcon} size={size} />\n    ),\n  },\n  {\n    name: \"reminders\",\n    Icon: ({ size }: { size: number }) => (\n      <HugeiconsIcon icon={ReminderIcon} size={size} />\n    ),\n  },\n  {\n    name: \"appointments\",\n    Icon: ({ size }: { size: number }) => (\n      <HugeiconsIcon icon={Appointment01Icon} size={size} />\n    ),\n  },\n  {\n    name: \"meetings\",\n    Icon: ({ size }: { size: number }) => (\n      <HugeiconsIcon icon={ZoomIcon} size={size} />\n    ),\n  },\n  {\n    name: \"celebrations\",\n    Icon: ({ size }: { size: number }) => (\n      <HugeiconsIcon icon={BalloonsIcon} size={size} />\n    ),\n  },\n];\n\nfunction ListItem(props: {\n  index: number;\n  filterKey: FilterKey;\n  selectedFilterKey: FilterKey;\n  setSelectedFilterKey: Dispatch<SetStateAction<FilterKey>>;\n  setIsOpened: Dispatch<SetStateAction<boolean>>;\n}) {\n  const {\n    index,\n    filterKey,\n    selectedFilterKey,\n    setSelectedFilterKey,\n    setIsOpened,\n  } = props;\n  const delay = (index + 8) * 0.025;\n\n  return (\n    <motion.div\n      initial={{ opacity: 0, y: 40 }}\n      animate={{ opacity: 1, y: 0 }}\n      transition={{\n        type: \"spring\",\n        bounce: 0.1,\n        duration: 0.25,\n        delay,\n        ease: [0.215, 0.61, 0.355, 1],\n      }}\n      onClick={() => {\n        setSelectedFilterKey(filterKey);\n\n        setTimeout(() => {\n          setIsOpened(false);\n        }, 150);\n      }}\n      className=\"px-3 py-2 rounded-2xl flex justify-between items-center cursor-default hover:bg-accent  text-foreground\"\n    >\n      <div className=\"flex items-center gap-x-3\">\n        <span className=\"text-muted-foreground\">\n          <filterKey.Icon size={24} />\n        </span>\n        <span className=\"capitalize\">{filterKey.name}</span>\n      </div>\n      <div\n        className={clsx(\n          \"relative border-border w-6 h-6 overflow-hidden rounded-full\",\n          selectedFilterKey.name == filterKey.name\n            ? \"border-none\"\n            : \"border-[2px]\"\n        )}\n      >\n        {selectedFilterKey.name == filterKey.name && (\n          <div className=\"absolute inset-0 bg-primary flex justify-center items-center text-primary-foreground\">\n            <HugeiconsIcon icon={Tick02Icon} size={16} />\n          </div>\n        )}\n      </div>\n    </motion.div>\n  );\n}\n\nconst FilterInteraction = () => {\n  const [selectedFilterKey, setSelectedFilterKey] = useState(filterKeys[0]);\n  const [isOpened, setIsOpened] = useState(false);\n\n  return (\n    <section className=\"flex justify-center items-center fill-muted-foreground/70\">\n      <MotionConfig\n        transition={{ type: \"spring\", duration: 0.85, bounce: 0.35 }}\n      >\n        <div\n          onClick={() => setIsOpened(true)}\n          className=\"relative left-2.5 w-20 h-20 flex justify-center items-center\"\n        >\n          <HugeiconsIcon\n            icon={FilterHorizontalIcon}\n            className=\"text-foreground relative z-10 fill-none\"\n            size={36}\n          />\n          <motion.div\n            layoutId=\"wrapper\"\n            className=\"absolute inset-0 z-[2] bg-background border-border\"\n            style={{ borderRadius: 40, borderWidth: 1 }}\n          />\n        </div>\n        <motion.div\n          initial={{ x: 0 }}\n          animate={{\n            x: isOpened ? -20 : 0,\n            // transition: { delay: isOpened ? 0 : 0.2 },\n          }}\n          transition={{ type: \"spring\", bounce: 0.3, duration: 1.5 }}\n          className=\"relative right-2.5 w-20 h-20 border border-border rounded-full flex justify-center items-center bg-background\"\n        >\n          <span className=\"text-muted-foreground\">\n            <selectedFilterKey.Icon size={36} />\n          </span>\n        </motion.div>\n\n        {isOpened && (\n          <motion.section\n            layoutId=\"wrapper\"\n            className=\"absolute z-20 w-72 px-1 py-1 bg-card border border-border text-xl overflow-hidden \"\n            style={{ borderRadius: 20, borderWidth: 1 }}\n          >\n            <div className=\"flex flex-col gap-1\">\n              {filterKeys.map((item, index) => (\n                <ListItem\n                  key={item.name}\n                  index={index}\n                  filterKey={item}\n                  selectedFilterKey={selectedFilterKey}\n                  setSelectedFilterKey={setSelectedFilterKey}\n                  setIsOpened={setIsOpened}\n                />\n              ))}\n            </div>\n          </motion.section>\n        )}\n      </MotionConfig>\n    </section>\n  );\n};\n\nexport default FilterInteraction;\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component"
}