π― Modern React component for smooth height animations - Perfect for accordions, dropdowns, and collapsible content with beautiful CSS transitions.
- β Smooth Animations - CSS-based height transitions with 60fps performance
- β React 18 Full Support - Perfect compatibility with latest React features
- β TypeScript Ready - Complete type definitions and IntelliSense support
- β Lightweight - Minimal bundle size with maximum performance
- β Customizable - Free styling with CSS for any animation style
- β Accessible - Screen reader and keyboard navigation support
npm install @smith6423/react-accordion --saveimport React, { useState } from "react";
import { Accordion } from "@smith6423/react-accordion";
import "@smith6423/react-accordion/lib/accordion.css";
function MyComponent() {
const [isOpen, setIsOpen] = useState(false);
return (
<div>
<button onClick={() => setIsOpen(!isOpen)}>
{isOpen ? "Close" : "Open"}
</button>
<Accordion>
{isOpen ? (
<div style={{ padding: "20px", background: "#f0f0f0" }}>
<h3>Animated Content!</h3>
<p>This content slides smoothly.</p>
</div>
) : null}
</Accordion>
</div>
);
}| Property | Type | Default | Required | Description |
|---|---|---|---|---|
| children | ReactNode | β | Content to display. Opens when provided, closes when removed | |
| closed | boolean | false | β | Forces close even when children are provided |
| className | string | β | Additional CSS class name | |
| transitionOnAppear | boolean | true | β | Whether to animate on initial mount |
| as | string | 'div' | β | HTML element type to render |
Freely customize animations through CSS:
/* Fast animation */
.react-accordion.fast {
transition-duration: 0.2s;
}
/* Slow animation */
.react-accordion.slow {
transition-duration: 1s;
}
/* Bounce effect */
.react-accordion.bounce {
transition-duration: 0.6s;
transition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
/* Smooth ease-out */
.react-accordion.smooth {
transition-duration: 0.4s;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}Direct access to DOM elements:
import React, { useRef } from "react";
import { Accordion } from "@smith6423/react-accordion";
function MyComponent() {
const accordionRef = useRef(null);
const scrollToAccordion = () => {
accordionRef.current?.scrollIntoView({ behavior: "smooth" });
};
return (
<div>
<button onClick={scrollToAccordion}>Scroll to Accordion</button>
<Accordion ref={accordionRef}>{/* Content */}</Accordion>
</div>
);
}function AccordionItem({ title, children, isOpen, onToggle }) {
return (
<div className="accordion-item">
<div className="accordion-header" onClick={onToggle}>
<h3>{title}</h3>
<span className={`icon ${isOpen ? "rotated" : ""}`}>βΌ</span>
</div>
<Accordion className="smooth">
{isOpen ? <div className="accordion-content">{children}</div> : null}
</Accordion>
</div>
);
}function Dropdown({ trigger, children }) {
const [isOpen, setIsOpen] = useState(false);
return (
<div className="dropdown">
<div onClick={() => setIsOpen(!isOpen)}>{trigger}</div>
<Accordion>
{isOpen ? <div className="dropdown-menu">{children}</div> : null}
</Accordion>
</div>
);
}function FAQ() {
const [openItems, setOpenItems] = useState(new Set());
const toggleItem = (index) => {
setOpenItems((prev) => {
const newSet = new Set(prev);
if (prev.has(index)) {
newSet.delete(index);
} else {
newSet.clear(); // Single selection
newSet.add(index);
}
return newSet;
});
};
const faqs = [
{
question: "How does this component work?",
answer: "It provides smooth height animations using CSS transitions.",
},
// More FAQs...
];
return (
<div className="faq-container">
{faqs.map((faq, index) => (
<div key={index} className="faq-item">
<button className="faq-question" onClick={() => toggleItem(index)}>
{faq.question}
</button>
<Accordion className="smooth">
{openItems.has(index) ? (
<div className="faq-answer">{faq.answer}</div>
) : null}
</Accordion>
</div>
))}
</div>
);
}function DynamicContent() {
const [content, setContent] = useState("Short text");
const [isOpen, setIsOpen] = useState(true);
const toggleContent = () => {
setContent((prev) =>
prev === "Short text"
? "This is much longer text. The animation smoothly adjusts even when content changes."
: "Short text"
);
};
return (
<div>
<button onClick={toggleContent}>Change Content</button>
<Accordion>
{isOpen ? <div className="content">{content}</div> : null}
</Accordion>
</div>
);
}function NestedAccordion() {
const [parentOpen, setParentOpen] = useState(false);
const [childOpen, setChildOpen] = useState(false);
return (
<div>
<button onClick={() => setParentOpen(!parentOpen)}>
{parentOpen ? "Close" : "Open"} Parent
</button>
<Accordion>
{parentOpen ? (
<div className="parent-content">
<h3>Parent Content</h3>
<button onClick={() => setChildOpen(!childOpen)}>
{childOpen ? "Close" : "Open"} Child
</button>
<Accordion className="nested">
{childOpen ? (
<div className="child-content">
<p>Nested accordion content</p>
</div>
) : null}
</Accordion>
</div>
) : null}
</Accordion>
</div>
);
}- createRoot API full support
- Concurrent Features compatible
- StrictMode works perfectly
- Automatic Batching optimized
- New TypeScript types defined
// React 18 way
import { createRoot } from "react-dom/client";
const container = document.getElementById("root");
const root = createRoot(container);
root.render(<App />);.react-accordion {
/* Default settings are automatically applied */
transition-duration: 0.5s;
transition-timing-function: ease-in-out;
}/* Dark theme */
.accordion-dark {
background: #2d3748;
color: white;
border-radius: 8px;
}
/* Gradient effect */
.accordion-gradient {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
transition-duration: 0.3s;
}
/* Shadow effect */
.accordion-shadow {
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
transition: box-shadow 0.3s ease;
}
.accordion-shadow.transitioning {
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
}- CSS-based animations: GPU acceleration utilized
- Memory efficiency: Minimal unnecessary re-renders
- Bundle size: Lightweight codebase
- Tree Shaking: Automatic unused code removal
- Chrome 26+
- Firefox 16+
- Safari 9+
- Edge 12+
- Internet Explorer 10+
MIT
Issues and PRs are always welcome!
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Create better user experiences with smooth animations! π