Skip to content

Conversation

joseph0926
Copy link

Description

This PR adds asChild support to the Accordion component, allowing users to compose the trigger with their own custom components. This aligns with Radix UI's composition patterns and provides greater flexibility for customization.

Problem

When attempting to use asChild prop with AccordionTrigger, users encounter the following error

React.Children.only expected to receive a single React element child.

This occurs because the current implementation renders multiple children (content + icon), which is incompatible with Radix UI's Slot component that requires a single child element for prop merging.

Solution

Following Radix UI's Slot component pattern, I've implemented conditional rendering that

  • Renders only the children when asChild is true (ensuring single element)
  • Renders children with icon when asChild is false (maintaining current behavior)

Changes Made

Modified Files

  • apps/www/registry/default/ui/accordion.tsx
  • apps/www/registry/new-york/ui/accordion.tsx

Key Implementation

interface AccordionTriggerProps extends React.ComponentProps<typeof AccordionPrimitive.Trigger> {
  asChild?: boolean
  hideIcon?: boolean
  icon?: React.ReactNode
}

function AccordionTrigger({
  asChild = false,
  hideIcon = false,
  icon,
  ...props
}: AccordionTriggerProps) {
  const Comp = asChild ? Slot : "button"
  // Conditional rendering based on asChild prop
}

Testing

  • Tested existing accordion functionality (no breaking changes)
  • Tested asChild prop with custom components
  • Tested icon customization props (hideIcon, icon)
  • Verified event handler merging
  • Verified ref forwarding
  • Built registry with pnpm build:registry

Usage Examples

// Default usage (unchanged)
<AccordionTrigger>Settings</AccordionTrigger>

// With asChild
<AccordionTrigger asChild>
  <CustomButton>
    <Icon />
    <span>Custom Trigger</span>
  </CustomButton>
</AccordionTrigger>

// Hide icon
<AccordionTrigger hideIcon>No Icon</AccordionTrigger>

// Custom icon
<AccordionTrigger icon={<PlusIcon />}>Custom Icon</AccordionTrigger>

Checklist

  • Changes made for both default and new-york styles
  • No breaking changes to existing API
  • TypeScript types properly defined and exported
  • Registry updated with pnpm build:registry
  • Documentation updated (if needed, can add examples to accordion docs)

Additional Notes

This implementation

  • Maintains 100% backward compatibility
  • Follows Radix UI's composition philosophy
  • Provides additional flexibility through hideIcon and icon props
  • Exports AccordionTriggerProps type for TypeScript users

Related issues

Closes #4732

Related documents

Copy link

vercel bot commented Aug 5, 2025

@joseph0926 is attempting to deploy a commit to the shadcn-pro Team on Vercel.

A member of the Team first needs to authorize it.

@joseph0926 joseph0926 closed this Aug 17, 2025
@joseph0926 joseph0926 deleted the joseph0926/fix-accordion-aschild branch August 17, 2025 00:29
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.

[bug]: AccordionTrigger throws error with asChild
1 participant