React hooks providing accordion state logic, item management, and context access for building custom accordion implementations.
Root hook providing all state and focus management logic for accordion items.
/**
* useAccordion hook provides all the state and focus management logic
* for accordion items.
*/
declare function useAccordion(props: UseAccordionProps): UseAccordionReturn;
interface UseAccordionProps {
/** If true, multiple accordion items can be expanded at once */
allowMultiple?: boolean;
/** If true, any expanded accordion item can be collapsed again */
allowToggle?: boolean;
/** The index(es) of the expanded accordion item */
index?: number | number[];
/** The initial index(es) of the expanded accordion item */
defaultIndex?: number | number[];
/** The callback invoked when accordion items are expanded or collapsed */
onChange?(expandedIndex: number | number[]): void;
}
interface UseAccordionReturn {
/** Current expanded index(es) */
index: number | number[];
/** Function to update expanded index(es) */
setIndex: React.Dispatch<React.SetStateAction<number | number[]>>;
/** Props for the root accordion element */
htmlProps: React.HTMLAttributes<HTMLElement>;
/** Function to get props for child accordion items */
getAccordionItemProps: (idx: number | null) => {
isOpen: boolean;
onChange: (isOpen: boolean) => void;
};
/** Currently focused accordion item index */
focusedIndex: number;
/** Function to update focused index */
setFocusedIndex: React.Dispatch<React.SetStateAction<number>>;
/** Descendant management utilities for focus control */
descendants: DescendantsManager<HTMLButtonElement>;
}Usage Examples:
import { useAccordion } from "@chakra-ui/accordion";
// Basic custom accordion implementation
function CustomAccordion({ children, ...props }) {
const { htmlProps, getAccordionItemProps, descendants } = useAccordion(props);
return (
<AccordionDescendantsProvider value={descendants}>
<div {...htmlProps} className="custom-accordion">
{children}
</div>
</AccordionDescendantsProvider>
);
}
// Controlled accordion with external state
function ControlledCustomAccordion() {
const [activeIndex, setActiveIndex] = React.useState(-1);
const accordion = useAccordion({
index: activeIndex,
onChange: setActiveIndex,
allowToggle: true
});
// Use accordion.getAccordionItemProps() for each item
return (
<div {...accordion.htmlProps}>
{/* Custom accordion items */}
</div>
);
}
// Multi-select accordion
function MultiSelectAccordion() {
const accordion = useAccordion({
allowMultiple: true,
defaultIndex: [0, 2]
});
return (
<div {...accordion.htmlProps}>
{/* Multiple items can be open simultaneously */}
</div>
);
}Hook providing open/close functionality for individual accordion items.
/**
* useAccordionItem - React hook that provides the open/close functionality
* for an accordion item and its children
*/
declare function useAccordionItem(props: UseAccordionItemProps): UseAccordionItemReturn;
interface UseAccordionItemProps {
/** If true, the accordion item will be disabled */
isDisabled?: boolean;
/** If true, the accordion item will be focusable */
isFocusable?: boolean;
/** A unique id for the accordion item */
id?: string;
}
interface UseAccordionItemReturn {
/** Whether the accordion item is currently open */
isOpen: boolean;
/** Whether the accordion item is disabled */
isDisabled?: boolean;
/** Whether the accordion item is focusable */
isFocusable?: boolean;
/** Function to expand the accordion item */
onOpen: () => void;
/** Function to collapse the accordion item */
onClose: () => void;
/** Function to get props for the accordion button element */
getButtonProps: (
props?: React.HTMLAttributes<HTMLElement>,
ref?: React.Ref<HTMLButtonElement>
) => React.ComponentProps<"button">;
/** Function to get props for the accordion panel element */
getPanelProps: <T>(
props?: React.HTMLAttributes<T>,
ref?: React.Ref<T>
) => React.HTMLAttributes<T> & React.RefAttributes<T>;
/** Additional HTML props for the accordion item container */
htmlProps: React.HTMLAttributes<HTMLElement>;
}Usage Examples:
import { useAccordionItem } from "@chakra-ui/accordion";
// Custom accordion item implementation
function CustomAccordionItem({ children, ...props }) {
const {
isOpen,
isDisabled,
onOpen,
onClose,
getButtonProps,
getPanelProps,
htmlProps
} = useAccordionItem(props);
return (
<div {...htmlProps} className="custom-accordion-item">
<button {...getButtonProps()}>
{isOpen ? "Collapse" : "Expand"} Item
</button>
<div {...getPanelProps()}>
{children}
</div>
</div>
);
}
// Accordion item with custom controls
function AccordionItemWithControls({ title, children, ...props }) {
const accordionItem = useAccordionItem(props);
return (
<div {...accordionItem.htmlProps}>
<div className="item-header">
<button {...accordionItem.getButtonProps()}>
{title}
</button>
<div className="controls">
<button onClick={accordionItem.onOpen} disabled={accordionItem.isOpen}>
Open
</button>
<button onClick={accordionItem.onClose} disabled={!accordionItem.isOpen}>
Close
</button>
</div>
</div>
<div {...accordionItem.getPanelProps()}>
{children}
</div>
</div>
);
}
// Disabled accordion item
function DisabledAccordionItem({ children }) {
const accordionItem = useAccordionItem({
isDisabled: true,
isFocusable: true // Still focusable for accessibility
});
return (
<div {...accordionItem.htmlProps} className="disabled-item">
<button {...accordionItem.getButtonProps()}>
Disabled Item (Focusable)
</button>
<div {...accordionItem.getPanelProps()}>
{children}
</div>
</div>
);
}Hook to access the accordion context for accessing root-level state and methods.
/**
* Hook to access accordion context (root level state)
*/
declare function useAccordionContext(): AccordionContext;
interface AccordionContext {
/** Current expanded index(es) */
index: number | number[];
/** Function to update expanded index(es) */
setIndex: React.Dispatch<React.SetStateAction<number | number[]>>;
/** Function to get props for child accordion items */
getAccordionItemProps: (idx: number | null) => {
isOpen: boolean;
onChange: (isOpen: boolean) => void;
};
/** Currently focused accordion item index */
focusedIndex: number;
/** Function to update focused index */
setFocusedIndex: React.Dispatch<React.SetStateAction<number>>;
/** Whether motion/animations are reduced */
reduceMotion: boolean;
}Usage Examples:
import { useAccordionContext } from "@chakra-ui/accordion";
// Custom component that accesses accordion state
function AccordionStatus() {
const { index, focusedIndex, reduceMotion } = useAccordionContext();
return (
<div className="accordion-status">
<p>Open items: {Array.isArray(index) ? index.join(", ") : index}</p>
<p>Focused item: {focusedIndex}</p>
<p>Animations: {reduceMotion ? "Disabled" : "Enabled"}</p>
</div>
);
}
// Custom accordion item that uses context directly
function ContextAwareAccordionItem({ itemIndex, children }) {
const { getAccordionItemProps, setFocusedIndex } = useAccordionContext();
const { isOpen, onChange } = getAccordionItemProps(itemIndex);
return (
<div className="context-aware-item">
<button
onClick={() => {
onChange(!isOpen);
setFocusedIndex(itemIndex);
}}
>
{isOpen ? "Close" : "Open"} Item {itemIndex}
</button>
{isOpen && <div>{children}</div>}
</div>
);
}Hook to get the current state and actions of an accordion item.
/**
* React hook to get the state and actions of an accordion item
*/
declare function useAccordionItemState(): AccordionItemState;
interface AccordionItemState {
/** Whether the accordion item is currently open */
isOpen: boolean;
/** Function to close the accordion item */
onClose: () => void;
/** Whether the accordion item is disabled */
isDisabled?: boolean;
/** Function to open the accordion item */
onOpen: () => void;
}Usage Examples:
import { useAccordionItemState } from "@chakra-ui/accordion";
// Component that displays accordion item state
function AccordionItemStateDisplay() {
const { isOpen, isDisabled, onOpen, onClose } = useAccordionItemState();
return (
<div className="item-state-display">
<p>Status: {isOpen ? "Open" : "Closed"}</p>
<div className="state-controls">
<button onClick={onOpen} disabled={isOpen || isDisabled}>
Open
</button>
<button onClick={onClose} disabled={!isOpen || isDisabled}>
Close
</button>
</div>
</div>
);
}
// Custom accordion panel with state-aware content
function StateAwarePanel({ children }) {
const { isOpen } = useAccordionItemState();
return (
<div className={`panel ${isOpen ? "panel-open" : "panel-closed"}`}>
<div className="panel-content">
{children}
</div>
<div className="panel-footer">
<small>Panel is {isOpen ? "expanded" : "collapsed"}</small>
</div>
</div>
);
}
// Conditional rendering based on state
function ConditionalContent() {
const { isOpen } = useAccordionItemState();
return (
<div>
{isOpen ? (
<div>This content only shows when expanded</div>
) : (
<div>This content only shows when collapsed</div>
)}
</div>
);
}Hook to access accordion styling context from the Chakra UI theme system.
/**
* Hook to access accordion styling context
*/
declare function useAccordionStyles(): Record<string, SystemStyleObject>;
interface SystemStyleObject {
[property: string]: any;
}Usage Examples:
import { useAccordionStyles } from "@chakra-ui/accordion";
// Custom component that uses accordion styles
function StyledAccordionItem() {
const styles = useAccordionStyles();
return (
<div style={styles.container}>
<button style={styles.button}>
Custom Styled Button
</button>
<div style={styles.panel}>
Custom Styled Panel
</div>
</div>
);
}
// Component that extends default styles
function ExtendedStyledItem() {
const styles = useAccordionStyles();
const customButtonStyles = {
...styles.button,
backgroundColor: "blue.500",
color: "white"
};
return (
<div style={styles.container}>
<button style={customButtonStyles}>
Extended Styled Button
</button>
<div style={styles.panel}>
Panel with default styles
</div>
</div>
);
}/**
* Context provider for accordion state
*/
declare const AccordionProvider: React.ComponentType<{
value: AccordionContext;
children: React.ReactNode;
}>;
/**
* Context provider for accordion descendant management
*/
declare const AccordionDescendantsProvider: React.ComponentType<{
value: DescendantsManager<HTMLButtonElement>;
children: React.ReactNode;
}>;
interface DescendantsManager<T extends HTMLElement> {
descendants: Map<HTMLElement, DescendantOptions>;
register: (node: T | null) => void;
unregister: (node: T) => void;
destroy: () => void;
assignIndex: (node: T) => number;
count: () => number;
enabledCount: () => number;
values: () => Descendant<T>[];
item: (index: number) => Descendant<T> | undefined;
enabled: () => Descendant<T>[];
first: () => Descendant<T> | undefined;
last: () => Descendant<T> | undefined;
indexOf: (node: T) => number;
next: (index: number, loop?: boolean) => Descendant<T> | undefined;
prev: (index: number, loop?: boolean) => Descendant<T> | undefined;
nextEnabled: (index: number, loop?: boolean) => Descendant<T> | undefined;
prevEnabled: (index: number, loop?: boolean) => Descendant<T> | undefined;
firstEnabled: () => Descendant<T> | undefined;
lastEnabled: () => Descendant<T> | undefined;
}