Accordion
The Accordion components (AccordionGroup and AccordionItem) allow you to create expandable panels for organizing content. These are part of the React package and use the Gaya design system.
Installation
npm install @naturacosmeticos/natds-react
Usage
import { AccordionGroup, AccordionItem } from '@naturacosmeticos/natds-react';
import { useState } from 'react';
function AccordionExample() {
const [activeIndex, setActiveIndex] = useState(null);
const handleToggle = (index) => {
setActiveIndex(activeIndex === index ? null : index);
};
return (
<AccordionGroup>
<AccordionItem
title="Section 1"
isActive={activeIndex === 0}
onClick={() => handleToggle(0)}
>
Content for section 1
</AccordionItem>
<AccordionItem
title="Section 2"
isActive={activeIndex === 1}
onClick={() => handleToggle(1)}
>
Content for section 2
</AccordionItem>
<AccordionItem
title="Section 3"
isActive={activeIndex === 2}
onClick={() => handleToggle(2)}
>
Content for section 3
</AccordionItem>
</AccordionGroup>
);
}
Accordion Variants
Regular Accordion
Default accordion with standard styling:
<AccordionGroup>
<AccordionItem
title="Regular Item"
color="regular"
isActive={isActive}
onClick={handleToggle}
>
This is a regular accordion item with standard background.
</AccordionItem>
</AccordionGroup>
Primary Colored Accordion
Accordion with primary color styling:
<AccordionGroup>
<AccordionItem
title="Primary Item"
color="primary"
isActive={isActive}
onClick={handleToggle}
>
This item uses the primary brand color.
</AccordionItem>
</AccordionGroup>
With Legend/Subtitle
Add a legend (subtitle) to accordion items:
<AccordionItem
title="Section Title"
legend="Additional information"
isActive={isActive}
onClick={handleToggle}
>
Content goes here
</AccordionItem>
Disabled Accordion
Prevent interaction with disabled state:
<AccordionItem
title="Disabled Item"
isDisabled={true}
isActive={false}
onClick={handleToggle}
>
This content won't be accessible
</AccordionItem>
Controlled vs Uncontrolled
Controlled Accordion
Manage accordion state externally:
function ControlledAccordion() {
const [expanded, setExpanded] = useState(0);
return (
<AccordionGroup>
{items.map((item, index) => (
<AccordionItem
key={index}
title={item.title}
isActive={expanded === index}
onClick={() => setExpanded(index)}
>
{item.content}
</AccordionItem>
))}
</AccordionGroup>
);
}
Multiple Panels Open
Allow multiple accordion items to be open simultaneously:
function MultipleAccordion() {
const [openItems, setOpenItems] = useState([]);
const handleToggle = (index) => {
setOpenItems(prev =>
prev.includes(index)
? prev.filter(i => i !== index)
: [...prev, index]
);
};
return (
<AccordionGroup>
{items.map((item, index) => (
<AccordionItem
key={index}
title={item.title}
isActive={openItems.includes(index)}
onClick={() => handleToggle(index)}
>
{item.content}
</AccordionItem>
))}
</AccordionGroup>
);
}
With Rich Content
<AccordionGroup>
<AccordionItem
title="Product Details"
legend="View specifications"
isActive={isActive}
onClick={handleToggle}
>
<div style={{ padding: '16px' }}>
<h3>Specifications</h3>
<ul>
<li>Weight: 500g</li>
<li>Dimensions: 10x10x5 cm</li>
<li>Material: Recyclable plastic</li>
</ul>
<p>Additional product information...</p>
</div>
</AccordionItem>
</AccordionGroup>
Brand Customization
import { BrandTypes } from '@naturacosmeticos/natds-react';
<AccordionItem
title="Branded Item"
brand="avon" // or 'natura', 'theBodyShop', etc.
isActive={isActive}
onClick={handleToggle}
>
Content styled according to brand theme
</AccordionItem>
Props
AccordionGroup
AccordionItem components to be grouped together.
Optional className to be added to the accordion group wrapper.
Optional ID for testing purposes.
AccordionItem
The text to display in the accordion header.
Function to toggle state between open and close.
Content that will be rendered when the AccordionItem is open.
color
'regular' | 'primary'
default:"'regular'"
Defines the style that will be applied to the accordion item.
Defines the state of the item (open/close).
If true, disables click events and changes color style.
Optional text used as a subtitle or additional information.
Brand theme to apply (e.g., ‘avon’, ‘natura’, ‘theBodyShop’).
Optional className to be added to the accordion item.
Optional ID for testing purposes.
Best Practices
- Always wrap AccordionItem components inside an AccordionGroup
- Manage accordion state in the parent component for better control
- Use meaningful titles that clearly indicate the content
- Consider using legends for additional context
- Avoid deeply nested accordions as they can confuse users
- For single-open behavior, track which item is active
- For multiple-open behavior, use an array to track open items
Accessibility
- The component automatically adds expand/collapse icons
- Icons change based on the
isActive state
- Disabled items have appropriate visual styling
- Ensure sufficient color contrast between text and background
- Consider adding ARIA attributes for better screen reader support
State Management Patterns
Single Panel Open
const [activeIndex, setActiveIndex] = useState(null);
const handleToggle = (index) => {
setActiveIndex(activeIndex === index ? null : index);
};
Multiple Panels Open
const [openPanels, setOpenPanels] = useState([]);
const handleToggle = (index) => {
setOpenPanels(prev =>
prev.includes(index)
? prev.filter(i => i !== index)
: [...prev, index]
);
};
Related Components