Skip to content

Conversation

@projectashik
Copy link

@projectashik projectashik commented Aug 3, 2025

I have create the registry for the accordion-faq component to try out for.

npx shadcn add https://animata.cban.top/r/accordion-faq.json

When this command is executed, it'll install @radix-ui/accordion, framer-motion and will create a file in components/animata/faq.tsx.

Summary by CodeRabbit

  • New Features

    • Introduced a new FAQ Accordion component with animated expand/collapse functionality.
    • Added a registry entry for the new FAQ Accordion component.
    • Included an "Open in V0" button for supported components in the preview interface.
  • Chores

    • Added a build script to automate cleaning and building component assets.
  • Style

    • Improved code cleanliness by reordering import statements and removing unnecessary blank lines in several files.

@coderabbitai
Copy link

coderabbitai bot commented Aug 3, 2025

Walkthrough

A new FAQ Accordion React component using Radix UI and Framer Motion was introduced and registered in a new JSON registry. Supporting changes include a new OpenInV0 utility component, its integration into ComponentPreview, import statement reordering in two files, a new package script, and the addition of a registry entry and component data.

Changes

Cohort / File(s) Change Summary
FAQ Accordion Component & Data
public/r/accordion-faq.json
Added a new FAQ Accordion React component using Radix UI and Framer Motion, with support for animated expand/collapse, icons, and styled answer bubbles.
Component Registry
registry.json
Introduced a registry file describing the new FAQ Accordion component, its dependencies, and file mapping for integration.
OpenInV0 Utility
components/open-in-v0.tsx
Added a new OpenInV0 React component that renders an external link for the "accordion-faq" component, with custom SVG icon and conditional rendering.
ComponentPreview Integration
components/component-preview.tsx
Integrated the OpenInV0 component into the preview, passing a sanitized name prop before the iframe.
Import Order Cleanup
animata/container/animated-dock.stories.tsx, animata/container/animated-dock.tsx
Reordered and grouped import statements for clarity; removed trailing blank lines. No logic changes.
Build Script Addition
package.json
Added a shadcn:build script to clean and rebuild the public registry directory.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ComponentPreview
    participant OpenInV0

    User->>ComponentPreview: Render (with name prop)
    ComponentPreview->>OpenInV0: Render (name prop)
    OpenInV0-->>ComponentPreview: Returns anchor (if name == "accordion-faq")
    ComponentPreview->>User: Renders OpenInV0 + iframe
Loading
sequenceDiagram
    participant User
    participant FaqSection

    User->>FaqSection: Render with FAQ data
    FaqSection->>FaqSection: Track open/closed state
    FaqSection->>User: Display accordion items
    User->>FaqSection: Click question
    FaqSection->>FaqSection: Animate expand/collapse
    FaqSection->>User: Show answer with animation
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~15 minutes

Poem

Hopping through code, a new FAQ appears,
With questions and answers to calm user fears.
Accordion expands with a gentle delight,
Animated with motion, styled just right.
A registry grows, a preview anew—
This bunny’s quite proud of the work you all do!
🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
components/open-in-v0.tsx (1)

17-26: Consider extracting SVG icon to improve maintainability.

The inline SVG icon is quite large and makes the component harder to read. Consider extracting it to a separate icon component or constant.

+const V0Icon = () => (
+  <svg viewBox="0 0 40 20" fill="none" xmlns="http://www.w3.org/2000/svg" className="size-5">
+    <path
+      d="M23.3919 0H32.9188C36.7819 0 39.9136 3.13165 39.9136 6.99475V16.0805H36.0006V6.99475C36.0006 6.90167 35.9969 6.80925 35.9898 6.71766L26.4628 16.079C26.4949 16.08 26.5272 16.0805 26.5595 16.0805H36.0006V19.7762H26.5595C22.6964 19.7762 19.4788 16.6139 19.4788 12.7508V3.68923H23.3919V12.7508C23.3919 12.9253 23.4054 13.0977 23.4316 13.2668L33.1682 3.6995C33.0861 3.6927 33.003 3.68923 32.9188 3.68923H23.3919V0Z"
+      fill="currentColor"
+    />
+    <path
+      d="M13.7688 19.0956L0 3.68759H5.53933L13.6231 12.7337V3.68759H17.7535V17.5746C17.7535 19.6705 15.1654 20.6584 13.7688 19.0956Z"
+      fill="currentColor"
+    />
+  </svg>
+);

       <span>Open in</span>
-      <svg viewBox="0 0 40 20" fill="none" xmlns="http://www.w3.org/2000/svg" className="size-5">
-        <path
-          d="M23.3919 0H32.9188C36.7819 0 39.9136 3.13165 39.9136 6.99475V16.0805H36.0006V6.99475C36.0006 6.90167 35.9969 6.80925 35.9898 6.71766L26.4628 16.079C26.4949 16.08 26.5272 16.0805 26.5595 16.0805H36.0006V19.7762H26.5595C22.6964 19.7762 19.4788 16.6139 19.4788 12.7508V3.68923H23.3919V12.7508C23.3919 12.9253 23.4054 13.0977 23.4316 13.2668L33.1682 3.6995C33.0861 3.6927 33.003 3.68923 32.9188 3.68923H23.3919V0Z"
-          fill="currentColor"
-        />
-        <path
-          d="M13.7688 19.0956L0 3.68759H5.53933L13.6231 12.7337V3.68759H17.7535V17.5746C17.7535 19.6705 15.1654 20.6584 13.7688 19.0956Z"
-          fill="currentColor"
-        />
-      </svg>
+      <V0Icon />
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1291701 and 605b667.

📒 Files selected for processing (7)
  • animata/container/animated-dock.stories.tsx (1 hunks)
  • animata/container/animated-dock.tsx (1 hunks)
  • components/component-preview.tsx (2 hunks)
  • components/open-in-v0.tsx (1 hunks)
  • package.json (1 hunks)
  • public/r/accordion-faq.json (1 hunks)
  • registry.json (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
components/component-preview.tsx (1)
components/open-in-v0.tsx (1)
  • OpenInV0 (1-29)
🔇 Additional comments (9)
package.json (1)

12-12: LGTM! Script supports registry build process.

The new shadcn:build script appropriately cleans the registry output directory before rebuilding, which aligns with the Shadcn registry integration objectives.

animata/container/animated-dock.tsx (1)

1-14: LGTM! Import organization improves code structure.

The import reordering follows good practices by grouping React/Next.js imports first, maintaining logical grouping within library imports, and placing utilities last. No functional changes were made.

animata/container/animated-dock.stories.tsx (1)

1-4: LGTM! Import reordering maintains consistency.

The import organization matches the changes made to the main animated-dock.tsx file, improving consistency across related files. No functional changes to the stories.

components/component-preview.tsx (2)

8-8: LGTM! OpenInV0 import supports new v0.dev integration.

The import statement correctly adds the new OpenInV0 utility component for Shadcn registry integration.


93-93: Suffix removal logic verified

  • Only one occurrence of name.replaceAll("--docs", "") exists in components/component-preview.tsx:93.
  • This will strip every --docs substring; with the current naming convention (appending --docs only as a suffix), it behaves as intended.
  • If you anticipate component names containing --docs elsewhere (not just at the end), you may opt for a stricter pattern, e.g.:
    name.replace(/--docs$/, "")
    to target only the trailing --docs.
registry.json (1)

1-21: Registry Definition Verified and Approved

All required dependencies and files are present and correctly configured:

  • “@radix-ui/react-accordion” and “framer-motion” entries found in package.json.
  • Source component file at animata/accordion/faq.tsx exists.
  • Public registry file at public/r/accordion-faq.json is generated.

No further changes needed.

components/open-in-v0.tsx (1)

10-14: LGTM: Proper security attributes and styling.

The external link implementation correctly uses target="_blank" with rel="noopener noreferrer" for security. The positioning and styling classes are appropriate for the UI placement.

public/r/accordion-faq.json (2)

1-7: LGTM: Proper registry schema and metadata.

The JSON structure correctly follows the Shadcn registry schema with appropriate metadata, component type, and dependencies specified.


12-14: LGTM: Correct file mapping configuration.

The file mapping correctly specifies the component type and target path for the Shadcn registry installation.

Comment on lines +5 to +7
if (name !== "accordion-faq") {
return null;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Remove hardcoded component filtering to improve reusability.

The hardcoded condition limiting functionality to only "accordion-faq" makes this component non-reusable and violates the DRY principle. This will require code changes for every new component added to the registry.

Consider one of these approaches:

Option 1: Remove the condition entirely (if all components should have this feature):

-  if (name !== "accordion-faq") {
-    return null;
-  }

Option 2: Make it configurable via props:

-export function OpenInV0({ name }: { name: string }) {
+export function OpenInV0({ name, enabled = true }: { name: string; enabled?: boolean }) {
   const registryUrl = `https://animata.cban.top/r/${name}.json`;
   const v0Url = `https://v0.dev/chat/api/open?url=${encodeURIComponent(registryUrl)}`;

-  if (name !== "accordion-faq") {
+  if (!enabled) {
     return null;
   }

Option 3: Accept a list of supported components:

-export function OpenInV0({ name }: { name: string }) {
+export function OpenInV0({ name, supportedComponents = [] }: { name: string; supportedComponents?: string[] }) {
   const registryUrl = `https://animata.cban.top/r/${name}.json`;
   const v0Url = `https://v0.dev/chat/api/open?url=${encodeURIComponent(registryUrl)}`;

-  if (name !== "accordion-faq") {
+  if (supportedComponents.length > 0 && !supportedComponents.includes(name)) {
     return null;
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (name !== "accordion-faq") {
return null;
}
export function OpenInV0({ name }: { name: string }) {
const registryUrl = `https://animata.cban.top/r/${name}.json`;
const v0Url = `https://v0.dev/chat/api/open?url=${encodeURIComponent(registryUrl)}`;
return (
<a href={v0Url} target="_blank" rel="noopener noreferrer">
{/* SVG icon */}
</a>
);
}
🤖 Prompt for AI Agents
In components/open-in-v0.tsx around lines 5 to 7, remove the hardcoded check for
"accordion-faq" to avoid limiting the component's reusability. Instead, either
eliminate the condition entirely if the feature should apply to all components,
or modify the component to accept a prop that specifies which component names
are supported, allowing dynamic filtering based on that prop. This change will
make the component more flexible and maintainable.

"files": [
{
"path": "animata/accordion/faq.tsx",
"content": "\"use client\";\n\nimport React, { useState } from \"react\";\nimport { motion } from \"framer-motion\";\n\nimport * as Accordion from \"@radix-ui/react-accordion\";\n\ninterface FAQItem {\n id: number;\n question: string;\n answer: string;\n icon?: string;\n iconPosition?: string;\n}\n\ninterface FaqSectionProps {\n data: FAQItem[];\n}\n\nexport default function FaqSection({ data }: FaqSectionProps) {\n const [openItem, setOpenItem] = useState<string | null>(null);\n\n return (\n <div\n className=\"mx-auto max-w-md rounded-lg bg-white p-4\"\n style={{ maxWidth: \"700px\", minWidth: \"700px\" }}\n >\n <div className=\"mb-4 text-sm text-gray-500\">Every day, 9:01 AM</div>\n\n <Accordion.Root\n type=\"single\"\n collapsible\n value={openItem || \"\"}\n onValueChange={(value) => setOpenItem(value)}\n >\n {data.map((item) => (\n <Accordion.Item value={item.id.toString()} key={item.id} className=\"mb-2\">\n <Accordion.Header>\n <Accordion.Trigger\n className=\"flex w-full items-center justify-start gap-x-4\"\n style={{ width: \"100%\" }}\n >\n <div\n className=\"relative flex items-center space-x-2 rounded-xl bg-gray-100 p-2 hover:bg-[#E0F7FA]\"\n style={{\n backgroundColor: openItem === item.id.toString() ? \"#E0F7FA\" : \"\",\n }}\n >\n {item.icon && (\n <span\n className={`absolute bottom-6 ${\n item.iconPosition === \"right\" ? \"right-0\" : \"left-0\"\n }`}\n style={{\n transform: item.iconPosition === \"right\" ? \"rotate(7deg)\" : \"rotate(-4deg)\",\n }}\n >\n {item.icon}\n </span>\n )}\n <span className=\"font-medium text-gray-700\">{item.question}</span>\n </div>\n\n <span className=\"cursor-pointer text-lg font-bold text-gray-400\">\n {openItem === item.id.toString() ? (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"#7CB9E8\"\n className=\"size-6\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25Zm3 10.5a.75.75 0 0 0 0-1.5H9a.75.75 0 0 0 0 1.5h6Z\"\n clipRule=\"evenodd\"\n />\n </svg>\n ) : (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n className=\"size-6\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25ZM12.75 9a.75.75 0 0 0-1.5 0v2.25H9a.75.75 0 0 0 0 1.5h2.25V15a.75.75 0 0 0 1.5 0v-2.25H15a.75.75 0 0 0 0-1.5h-2.25V9Z\"\n clipRule=\"evenodd\"\n />\n </svg>\n )}\n </span>\n </Accordion.Trigger>\n </Accordion.Header>\n <Accordion.Content asChild forceMount style={{ display: \"block\" }}>\n <motion.div\n initial=\"collapsed\"\n animate={openItem === item.id.toString() ? \"open\" : \"collapsed\"}\n variants={{\n open: { opacity: 1, height: \"auto\" },\n collapsed: { opacity: 0, height: 0 },\n }}\n transition={{ duration: 0.4 }}\n style={{ width: \"100%\", overflow: \"hidden\" }}\n >\n <div\n className=\"ml-7 mt-1 rounded-lg p-3 text-white md:ml-16\"\n style={{\n borderRadius: \"12px\",\n textAlign: \"left\",\n width: \"100%\",\n }}\n >\n <div className=\"relative max-w-xs rounded-2xl bg-blue-500 px-4 py-2 text-white\">\n {item.answer}\n <div className=\"absolute bottom-0 right-0 h-0 w-0 border-l-[10px] border-t-[10px] border-l-transparent border-t-blue-500\"></div>\n </div>\n </div>\n </motion.div>\n </Accordion.Content>\n </Accordion.Item>\n ))}\n </Accordion.Root>\n </div>\n );\n}\n",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Mix of inline styles and Tailwind classes creates inconsistency.

The component content mixes inline styles with Tailwind classes inconsistently, and has hardcoded dimensions that reduce flexibility.

Issues in the embedded component:

  1. Hardcoded dimensions: maxWidth: "700px", minWidth: "700px" should be configurable or use responsive Tailwind classes
  2. Mixed styling approaches: Some elements use inline styles while others use Tailwind classes
  3. Accessibility concerns: Missing ARIA attributes for accordion functionality

Consider these improvements for the embedded component:

Replace hardcoded dimensions:

-      style={{ maxWidth: "700px", minWidth: "700px" }}
+      className="mx-auto w-full max-w-2xl rounded-lg bg-white p-4"

Use consistent Tailwind classes instead of inline styles:

-                style={{
-                  backgroundColor: openItem === item.id.toString() ? "#E0F7FA" : "",
-                }}
+                className={`relative flex items-center space-x-2 rounded-xl p-2 transition-colors hover:bg-cyan-50 ${
+                  openItem === item.id.toString() ? "bg-cyan-50" : "bg-gray-100"
+                }`}

Add accessibility attributes:

               <Accordion.Trigger
-                className="flex w-full items-center justify-start gap-x-4"
+                className="flex w-full items-center justify-start gap-x-4"
+                aria-expanded={openItem === item.id.toString()}

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In public/r/accordion-faq.json at line 11, the embedded React component mixes
inline styles with Tailwind CSS classes and uses hardcoded fixed widths,
reducing flexibility and consistency. To fix this, replace the fixed inline
styles for maxWidth and minWidth with responsive Tailwind width classes (e.g.,
max-w-xl or max-w-2xl) to allow better responsiveness. Remove inline style
objects where possible and convert those styles into equivalent Tailwind utility
classes for consistency. Additionally, add appropriate ARIA attributes to the
Accordion elements to improve accessibility, such as aria-expanded and
aria-controls on triggers and roles on accordion items.

@hari
Copy link
Contributor

hari commented Sep 5, 2025

Thanks for the PR @projectashik. I will create a dedicated registry and add all components.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants