Creating AccordionItem
Second, create an AccordionItem
component with the useAccordionItem
and
useAccordionItemEffect
hook exported from the library.
Without height transition
Use the following code if you don't need the height transition for expanding and collapsing items.
import {
useAccordionItem,
useAccordionItemEffect
} from '@szhsin/react-accordion';
import ChevronDown from '@site/static/img/chevron-down.svg';
import styles from '../accordion/styles.module.css';
const AccordionItem = ({
header,
children,
itemKey,
initialEntered,
disabled
}: {
header: React.ReactNode;
children: React.ReactNode;
itemKey?: string | number;
initialEntered?: boolean;
disabled?: boolean;
}) => {
const { itemRef, state, toggle } =
useAccordionItemEffect<HTMLDivElement>({
itemKey,
initialEntered,
disabled
});
const { buttonProps, panelProps } = useAccordionItem({
state,
toggle,
disabled
});
const { status, isMounted, isEnter } = state;
return (
<div className={styles.item} ref={itemRef}>
{/* Choose a heading level that is appropriate for the information
architecture of your page */}
<h3 style={{ margin: 0 }}>
<button
className={isEnter ? styles.buttonExpanded : styles.button}
type="button"
{...buttonProps}
>
{header}
<ChevronDown className={styles.chevron} />
</button>
</h3>
{isMounted && (
<div
className={styles.panel}
style={{
display: status === 'exited' ? 'none' : undefined
}}
{...panelProps}
>
{children}
</div>
)}
</div>
);
};
export default AccordionItem;
Height transition
Use the useHeightTransition
hook and add a wrapping div
around the accordion item
children if you want the height transition for expanding and collapsing items.
import {
useAccordionItem,
useAccordionItemEffect,
useHeightTransition
} from '@szhsin/react-accordion';
import ChevronDown from '@site/static/img/chevron-down.svg';
import styles from '../accordion/styles.module.css';
const AccordionItem = ({
header,
children,
itemKey,
initialEntered,
disabled
}: {
header: React.ReactNode;
children: React.ReactNode;
itemKey?: string | number;
initialEntered?: boolean;
disabled?: boolean;
}) => {
const { itemRef, state, toggle } =
useAccordionItemEffect<HTMLDivElement>({
itemKey,
initialEntered,
disabled
});
const { buttonProps, panelProps } = useAccordionItem({
state,
toggle,
disabled
});
const [transitionStyle, panelRef] =
useHeightTransition<HTMLDivElement>(state);
const { status, isMounted, isEnter } = state;
return (
<div className={styles.item} ref={itemRef}>
<h3 style={{ margin: 0 }}>
<button
className={isEnter ? styles.buttonExpanded : styles.button}
type="button"
{...buttonProps}
>
{header}
<ChevronDown className={styles.chevron} />
</button>
</h3>
{isMounted && (
// Add an extra `div` around the panel `div` for the
// height transition to work as intended
<div
className={styles.content}
style={{
display: status === 'exited' ? 'none' : undefined,
...transitionStyle
}}
>
<div
className={styles.panel}
ref={panelRef}
{...panelProps}
>
{children}
</div>
{/* Closing tag of the extra `div` */}
</div>
)}
</div>
);
};
export default AccordionItem;