shadimage
indiacn
uiaccordionsource: ok · refreshed

Accordion

Vertically-stacked collapsible sections. Built on Radix Accordion primitive.

npx shadcn add "https://indiacn.in/r/accordion.json"
free

Interaction

accordion

Tags auto-generated by rules on 9/24/2026 — empty means no evidence, not lack of support.

Dependencies

Bundle weight · light
ui-primitives@radix-ui/react-accordion
iconslucide-react

Registry dependencies

https://indiacn.in/r/theme.json

Files1 · source cached 10/8/2026, 5:35:25 AM

components/ui/accordion.tsx
'use client';

import * as AccordionPrimitive from '@radix-ui/react-accordion';
import { ChevronDown } from 'lucide-react';
import { ComponentProps } from 'react';

import { cn } from '@/lib/utils';

/*
 * UX4G accordion: item has a single bottom border in neutral-100; trigger and
 * body both pad 16px/20px; trigger type is label-1; chevron is 24px. The open
 * item is not outlined — only the focus ring is.
 */

/** Accordion root component. */
function Accordion({ className, ...props }: ComponentProps<typeof AccordionPrimitive.Root>) {
  return <AccordionPrimitive.Root className={cn('w-full', className)} {...props} />;
}

interface IAccordionItemProps extends ComponentProps<typeof AccordionPrimitive.Item> {
  borderless?: boolean;
}

/** Single collapsible accordion item. `borderless` drops the divider. */
function AccordionItem({ className, borderless, ...props }: IAccordionItemProps) {
  return (
    <AccordionPrimitive.Item
      className={cn('border-b border-neutral-100', borderless && 'border-b-0', className)}
      {...props}
    />
  );
}

/** Clickable trigger that toggles an accordion item. */
function AccordionTrigger({
  className,
  children,
  ...props
}: ComponentProps<typeof AccordionPrimitive.Trigger>) {
  return (
    <AccordionPrimitive.Header className='flex'>
      <AccordionPrimitive.Trigger
        className={cn(
          'text-neutral flex flex-1 cursor-pointer items-center justify-between px-5 py-4 text-sm font-medium tracking-[0.1px] transition-all',
          // No Accordion page in the Figma kit, so this follows the library's own
          // convention for a text-on-surface control rather than inventing values.
          'hover:bg-primary/8 active:bg-primary/16 disabled:pointer-events-none disabled:opacity-50',
          'focus-visible:border-primary focus-visible:shadow-focus-primary focus-visible:z-3 focus-visible:rounded-lg focus-visible:border focus-visible:outline-none',
          '[&[data-state=open]>svg]:rotate-180',
          className,
        )}
        {...props}
      >
        {children}
        <ChevronDown className='size-6 shrink-0 text-neutral-500 transition-transform duration-200' />
      </AccordionPrimitive.Trigger>
    </AccordionPrimitive.Header>
  );
}

/** Collapsible content panel for an accordion item. */
function AccordionContent({
  className,
  children,
  ...props
}: ComponentProps<typeof AccordionPrimitive.Content>) {
  return (
    <AccordionPrimitive.Content
      className='data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm'
      {...props}
    >
      <div className={cn('px-5 py-4', className)}>{children}</div>
    </AccordionPrimitive.Content>
  );
}

export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };

More from indiacn

Browse all components in this library →