The accordion component allows the user to show and hide sections of related content on a page.
import { Accordion, AccordionItem, AccordionProvider, ControlledAccordion, withAccordionItem } from "@wfp/react"
An accordion is created by wrapping any number of AccordionItem components inside an Accordion component.
By default, only one accordion item can be expanded at one time.
import { Accordion, AccordionItem } from "@wfp/react"; <Accordion> <AccordionItem header="What is Lorem Ipsum?"> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </AccordionItem> <AccordionItem header="Where does it come from?"> Quisque eget luctus mi, vehicula mollis lorem. Proin fringilla vel erat quis sodales. Nam ex enim, eleifend venenatis lectus vitae, accumsan auctor mi. </AccordionItem> <AccordionItem header="Why do we use it?"> Suspendisse massa risus, pretium id interdum in, dictum sit amet ante. Fusce vulputate purus sed tempus feugiat. </AccordionItem> </Accordion>;
To allow multiple accordion items to expand at once, set the allowMultiple prop of the Accordion component.
<Accordion allowMultiple />
You could use the initialEntered prop of AccordionItem to expand items when accordion first mounts. In the following example, the first and last item are expanded on mount.
<AccordionItem header="What is Lorem Ipsum?" initialEntered>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod temporincididunt ut labore et dolore magna aliqua.</AccordionItem>
Note
The Accordion component also has an initialEntered prop which can make every accordion item expanded when initially mounted.
When the initialEntered prop is specified on an individual AccordionItem at the same time, it overrides the initialEntered prop of Accordion component.
You may provide the header prop of AccordionItem with any JSX elements or React components, allowing the item header be to freely customized.
<AccordionItemheader={<div><p className={styles.title}>What is Lorem Ipsum?</p><p className={styles.description}>Lorem ipsum is a placeholder text commonly used to demonstrate thevisual form of a document.</p></div>}>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod temporincididunt ut labore et dolore magna aliqua.</AccordionItem>
If you want to programmatically open or close accordion items from a component that is above Accordion in the React tree, you could use the ControlledAccordion and useAccordionProvider.
The value returned from useAccordionProvider contains a toggle function which can be used to open or close any accordion items. This value should also be given to the providerValue prop of the ControlledAccordion component.
The toggle function accepts two parameters. The first parameter is the itemKey prop of any accordion items to toggle. The second parameter specifies whether to open or close an item using a boolean value, or to toggle between the two states if the parameter is omitted.
export default function Example() {const providerValue = useAccordionProvider({allowMultiple: true,transition: true,transitionTimeout: 200,});// Destructuring `toggle` and `toggleAll` from `providerValue`const { toggle, toggleAll } = providerValue;return (<div><div className="buttons"><buttonclassName="btn"// Toggle between open and close by omitting the second parameteronClick={() => toggle("item-1")}>Toogle the first item</button><buttonclassName="btn"// Open rather than togglingonClick={() => toggle("item-3", true)}>Open the last item</button><button className="btn" onClick={() => toggleAll(true)}>Open all items</button><button className="btn" onClick={() => toggleAll(false)}>Close all items</button><buttonclassName="btn"// Omitting the boolean parameter means togglingonClick={() => toggleAll()}>Toggle all items</button></div><ControlledAccordion// Forward the `providerValue` directly to `ControlledAccordion`providerValue={providerValue}><AccordionItemheader="What is Lorem Ipsum?"// Set an explicit `itemKey`itemKey="item-1"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed doeiusmod tempor incididunt ut labore et dolore magna aliqua.</p><buttonclassName="btn"// It also works within the `AccordionItem` childrenonClick={() => toggle("item-3")}>Toggle the last item</button></AccordionItem><AccordionItem header="Where does it come from?">Quisque eget luctus mi, vehicula mollis lorem. Proin fringilla velerat quis sodales. Nam ex enim, eleifend venenatis lectus vitae,accumsan auctor mi.</AccordionItem><AccordionItemheader="Why do we use it?"// Set an explicit `itemKey`itemKey="item-3">Suspendisse massa risus, pretium id interdum in, dictum sit amet ante.Fusce vulputate purus sed tempus feugiat.</AccordionItem></ControlledAccordion></div>);}
Info
The itemKey prop of AccordionItem is not required to be globally unique, but it should be unique among its sibling AccordionItem components.
Also, you don’t need to specify the itemKey prop for an item if you don’t want to programmatically toggle it.
To programmatically open or close accordion items or access the state from a component that is underneath Accordion in the React tree, use the useAccordionState hook.
Info
If you want to access and control state of the current item, there is a
simpler way to achieve it using the render prop
pattern.
Both the header and children props of AccordionItem component support the render prop pattern, which can be used to access item state, along with a toggle function to open or close the current item.
<AccordionItem// Accessing item state by giving a function to the `header` propheader={({ state }) => `Item expanded: ${state.isEnter}`}>{({ toggle }) => (<><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmodtempor incididunt ut labore et dolore magna aliqua.</p>{/* `toggle` function is also available from the render prop */}<button className="btn" onClick={() => toggle(false)}>Close item</button></>)}</AccordionItem>
<AccordionItem header="Where does it come from?" disabled />
Accordion items can be made disabled by adding the disabled prop. Disabled items cannot be toggled by clicking the header and are excluded from keyboard navigation.
The onStateChange event of Accordion can be used to listen to item state updates. The event object has a key prop identifying which item’s state has changed.
<AccordiononStateChange={({ key, current }) => {if (current.isResolved)console.log(`${key} is expanded: ${current.isEnter}`);}}>{items.map(({ header, content }, i) => (<AccordionItemkey={i}header={header}// Explicitly set `itemKey` prop for each itemitemKey={`Item-${i + 1}`}>{content}</AccordionItem>))}</Accordion>
Accordion supports expanding and collapsing animation with full state transition cycle, thanks to the react-transition-state library. You can follow the steps below to enable animation:
First, set transition and transitionTimeout props on the Accordion component.
<Accordion transition transitionTimeout={200}>{/* Accordion items... */}</Accordion>
Then, add the height transition CSS to the item content DOM element of each accordion item, which is the element with class selector wfp-accordion__item-content.
transition: height 0.2s ease-in-out;