{"$schema":"https://ui.shadcn.com/schema/registry-item.json","author":"Eduardo Calvo <educlopez93@gmail.com>","css":{},"dependencies":["motion"],"description":"FAQ accordion block with expandable questions","devDependencies":[],"files":[{"content":"\"use client\";\n\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport { useState } from \"react\";\n\nconst ANIMATION_DURATION = 0.6;\nconst STAGGER_DELAY = 0.1;\nconst INITIAL_Y_OFFSET = 20;\nconst HOVER_SCALE = 1.01;\nconst TAP_SCALE = 0.99;\nconst ROTATION_OPEN = 180;\nconst ROTATION_CLOSED = 0;\nconst CONTENT_DELAY = 0.1;\nconst INITIAL_CONTENT_Y = -10;\n\ninterface FaqsAccordionProps {\n  description?: string;\n  faqs?: Array<{\n    question: string;\n    answer: string;\n  }>;\n  title?: string;\n}\n\nexport function FaqsAccordion({\n  title = \"Frequently Asked Questions\",\n  description = \"Find answers to common questions about our product and services\",\n  faqs = [\n    {\n      answer:\n        \"Smoothui is a modern UI component library that provides beautiful, animated components for building stunning user interfaces. It includes pre-built components with smooth animations and customizable themes.\",\n      question: \"What is Smoothui?\",\n    },\n    {\n      answer:\n        \"Getting started is easy! Simply install the package via npm or yarn, import the components you need, and start building. We provide comprehensive documentation and examples to help you get up and running quickly.\",\n      question: \"How do I get started?\",\n    },\n    {\n      answer:\n        \"Yes! Smoothui is completely free and open source. You can use it in both personal and commercial projects without any restrictions. We believe in making beautiful UI components accessible to everyone.\",\n      question: \"Is it free to use?\",\n    },\n    {\n      answer:\n        \"Absolutely! All components are fully customizable. You can modify colors, spacing, animations, and more using CSS variables or by extending the component classes. We also provide a theming system for easy customization.\",\n      question: \"Can I customize the components?\",\n    },\n    {\n      answer:\n        \"Currently, Smoothui supports React and Next.js. We're working on expanding support to other popular frameworks like Vue, Svelte, and Angular in the coming months.\",\n      question: \"What frameworks are supported?\",\n    },\n    {\n      answer:\n        \"We release updates regularly, typically every 2-3 weeks. This includes new components, bug fixes, performance improvements, and new features. You can follow our changelog to stay updated on the latest releases.\",\n      question: \"How often do you release updates?\",\n    },\n  ],\n}: FaqsAccordionProps) {\n  const shouldReduceMotion = useReducedMotion();\n  const [openIndex, setOpenIndex] = useState<number | null>(0);\n\n  const toggleAccordion = (index: number) => {\n    setOpenIndex(openIndex === index ? null : index);\n  };\n\n  return (\n    <section className=\"py-20\">\n      <div className=\"mx-auto max-w-4xl px-6\">\n        <motion.div\n          animate={shouldReduceMotion ? { opacity: 1 } : { opacity: 1, y: 0 }}\n          className=\"mb-16 text-center\"\n          initial={\n            shouldReduceMotion\n              ? { opacity: 1 }\n              : { opacity: 0, y: INITIAL_Y_OFFSET }\n          }\n          transition={\n            shouldReduceMotion\n              ? { duration: 0 }\n              : { duration: ANIMATION_DURATION }\n          }\n          viewport={{ once: true }}\n          whileInView={\n            shouldReduceMotion ? { opacity: 1 } : { opacity: 1, y: 0 }\n          }\n        >\n          <h2 className=\"mb-4 font-bold text-3xl text-foreground lg:text-4xl\">\n            {title}\n          </h2>\n          <p className=\"mx-auto max-w-2xl text-foreground/70 text-lg\">\n            {description}\n          </p>\n        </motion.div>\n\n        <div className=\"space-y-4\">\n          {faqs.map((faq, index) => (\n            <motion.div\n              animate={\n                shouldReduceMotion ? { opacity: 1 } : { opacity: 1, y: 0 }\n              }\n              className=\"group overflow-hidden rounded-2xl border border-border bg-background transition-all hover:border-brand hover:shadow-lg\"\n              initial={\n                shouldReduceMotion\n                  ? { opacity: 1 }\n                  : { opacity: 0, y: INITIAL_Y_OFFSET }\n              }\n              key={faq.question}\n              transition={\n                shouldReduceMotion\n                  ? { duration: 0 }\n                  : {\n                      delay: index * STAGGER_DELAY,\n                      duration: ANIMATION_DURATION,\n                    }\n              }\n              viewport={{ once: true }}\n              whileInView={\n                shouldReduceMotion ? { opacity: 1 } : { opacity: 1, y: 0 }\n              }\n            >\n              <motion.button\n                className=\"flex w-full cursor-pointer items-center justify-between p-6 text-left transition-colors hover:bg-background/50\"\n                onClick={() => toggleAccordion(index)}\n                type=\"button\"\n                whileHover={shouldReduceMotion ? {} : { scale: HOVER_SCALE }}\n                whileTap={shouldReduceMotion ? {} : { scale: TAP_SCALE }}\n              >\n                <h3 className=\"pr-4 font-semibold text-foreground text-lg\">\n                  {faq.question}\n                </h3>\n                <motion.div\n                  animate={\n                    shouldReduceMotion\n                      ? {\n                          rotate:\n                            openIndex === index\n                              ? ROTATION_OPEN\n                              : ROTATION_CLOSED,\n                        }\n                      : {\n                          rotate:\n                            openIndex === index\n                              ? ROTATION_OPEN\n                              : ROTATION_CLOSED,\n                        }\n                  }\n                  className=\"flex-shrink-0\"\n                  transition={\n                    shouldReduceMotion\n                      ? { duration: 0 }\n                      : { duration: ANIMATION_DURATION, ease: \"easeInOut\" }\n                  }\n                >\n                  <svg\n                    aria-hidden=\"true\"\n                    className=\"h-5 w-5 text-foreground/60\"\n                    fill=\"none\"\n                    stroke=\"currentColor\"\n                    viewBox=\"0 0 24 24\"\n                  >\n                    <path\n                      d=\"M19 9l-7 7-7-7\"\n                      strokeLinecap=\"round\"\n                      strokeLinejoin=\"round\"\n                      strokeWidth={2}\n                    />\n                  </svg>\n                </motion.div>\n              </motion.button>\n\n              <AnimatePresence>\n                {openIndex === index && (\n                  <motion.div\n                    animate={{ height: \"auto\", opacity: 1 }}\n                    className=\"overflow-hidden\"\n                    exit={\n                      shouldReduceMotion\n                        ? { opacity: 0, transition: { duration: 0 } }\n                        : { height: 0, opacity: 0 }\n                    }\n                    initial={\n                      shouldReduceMotion\n                        ? { opacity: 1 }\n                        : { height: 0, opacity: 0 }\n                    }\n                    transition={\n                      shouldReduceMotion\n                        ? { duration: 0 }\n                        : { duration: ANIMATION_DURATION, ease: \"easeInOut\" }\n                    }\n                  >\n                    <motion.div\n                      animate={{ y: 0 }}\n                      className=\"px-6 pb-6\"\n                      exit={\n                        shouldReduceMotion\n                          ? { transition: { duration: 0 } }\n                          : { y: INITIAL_CONTENT_Y }\n                      }\n                      initial={\n                        shouldReduceMotion ? { y: 0 } : { y: INITIAL_CONTENT_Y }\n                      }\n                      transition={\n                        shouldReduceMotion\n                          ? { duration: 0 }\n                          : {\n                              delay: CONTENT_DELAY,\n                              duration: ANIMATION_DURATION,\n                            }\n                      }\n                    >\n                      <p className=\"text-foreground/70 leading-relaxed\">\n                        {faq.answer}\n                      </p>\n                    </motion.div>\n                  </motion.div>\n                )}\n              </AnimatePresence>\n            </motion.div>\n          ))}\n        </div>\n      </div>\n    </section>\n  );\n}\n\nexport default FaqsAccordion;\n","path":"index.tsx","target":"components/smoothui/faq-2/index.tsx","type":"registry:block"}],"name":"faq-2","registryDependencies":["https://smoothui.dev/r/tokens.json"],"title":"Faq 2","type":"registry:block"}