typescriptintermediate
Accordion Component
Accessible accordion component with keyboard navigation and animated expand/collapse.
typescriptPress ā/Ctrl + Shift + C to copy
import { useState, useRef, ReactNode } from 'react';
interface AccordionItemProps {
title: string;
children: ReactNode;
isOpen: boolean;
onToggle: () => void;
}
function AccordionItem({ title, children, isOpen, onToggle }: AccordionItemProps) {
const contentRef = useRef<HTMLDivElement>(null);
return (
<div className="border-b border-white/10">
<button
className="w-full flex justify-between items-center py-4 text-left"
onClick={onToggle}
aria-expanded={isOpen}
>
<span className="font-medium">{title}</span>
<span className={`transform transition-transform ${isOpen ? 'rotate-180' : ''}`}>ā¼</span>
</button>
<div
ref={contentRef}
style={{ maxHeight: isOpen ? contentRef.current?.scrollHeight : 0 }}
className="overflow-hidden transition-all duration-300"
>
<div className="pb-4">{children}</div>
</div>
</div>
);
}
interface AccordionProps {
items: { title: string; content: ReactNode }[];
allowMultiple?: boolean;
}
export function Accordion({ items, allowMultiple = false }: AccordionProps) {
const [openIndexes, setOpenIndexes] = useState<Set<number>>(new Set());
const toggle = (index: number) => {
setOpenIndexes(prev => {
const next = new Set(allowMultiple ? prev : []);
if (next.has(index)) next.delete(index);
else next.add(index);
return next;
});
};
return (
<div>
{items.map((item, i) => (
<AccordionItem key={i} title={item.title} isOpen={openIndexes.has(i)} onToggle={() => toggle(i)}>
{item.content}
</AccordionItem>
))}
</div>
);
}Use Cases
- FAQ sections
- Settings panels
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
typescriptintermediate
Portal Tooltip Component
Accessible tooltip rendered via Portal with automatic positioning and arrow indicator.
Best for: Icon button labels
#tooltip#portal
typescriptintermediate
Error Boundary with Fallback UI
Class-based error boundary component that catches render errors and displays a customizable fallback UI.
Best for: Graceful error recovery
#error-boundary#error-handling
typescriptintermediate
Portal-Based Modal Component
Accessible modal component using React portals with focus trapping, Escape key close, and backdrop click.
Best for: Confirmation dialogs
#modal#portal
typescriptintermediate
Accessible Tabs Component
Build an accessible tabs component with keyboard navigation, ARIA attributes, and focus management.
Best for: Tab navigation interfaces
#react#accessibility