Skip to content

smith6423/react-accordion

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

@smith6423/react-accordion

🎯 Modern React component for smooth height animations - Perfect for accordions, dropdowns, and collapsible content with beautiful CSS transitions.

npm version

πŸš€ Features

  • βœ… 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

πŸ“¦ Installation

npm install @smith6423/react-accordion --save

🎯 Basic Usage

import 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>
  );
}

πŸ“‹ Props

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

🎨 Animation Customization

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);
}

πŸ”— forwardRef Support

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>
  );
}

πŸ’‘ Real-world Examples

Accordion Component

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>
  );
}

Dropdown Menu

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>
  );
}

FAQ Section

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>
  );
}

🎯 Advanced Usage

Dynamic Content

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>
  );
}

Nested Accordions

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>
  );
}

🌟 React 18 Features

  • 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 />);

🎨 Styling Guide

Default Styles

.react-accordion {
  /* Default settings are automatically applied */
  transition-duration: 0.5s;
  transition-timing-function: ease-in-out;
}

Custom Themes

/* 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);
}

πŸš€ Performance Optimization

  • CSS-based animations: GPU acceleration utilized
  • Memory efficiency: Minimal unnecessary re-renders
  • Bundle size: Lightweight codebase
  • Tree Shaking: Automatic unused code removal

πŸ”§ Browser Support

  • Chrome 26+
  • Firefox 16+
  • Safari 9+
  • Edge 12+
  • Internet Explorer 10+

πŸ“ License

MIT

🀝 Contributing

Issues and PRs are always welcome!

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Create better user experiences with smooth animations! 🎊

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published