We'll use the Activatables
stateful component to control
expanding the Accordions. Each Activatables
component will act as a group of Accordions. This
will also allow easily configuring whether multiple accordions can be active simultaneously.
First we'll create an AnimatedTitle
component to animate the Accordion title using styled-components
.
Then we'll create an AccordionTitle
component, which uses the active
and onClick
props provided by the Activatable
stateful component to drive the AnimatedTitle
animation, as well as toggling the active
state on click.
import styled from 'styled-components'import { Activatable, Text, Button } from '@intouchg/components'const AnimatedTitle = styled(Text)`color: ${(props) => props.active ? 'green' : 'red'};`const AccordionTitle = ({ id, ...props }) => (<Activatable id={id}>{({ active, toggleActive }) => (<ButtoninvisibleonClick={toggleActive}><AnimatedTitleactive={active}{...props}/></Button>)}</Activatable>)export { AccordionTitle }
Next we'll create an AnimatedContent
component to animate the Accordion content using react-spring
. We
measure the Accordion content with the useMeasure
hook, and use the height
value in our active
animation.
Then we'll create an AccordionContent
component, which uses the active
prop provided by the Activatable
stateful
component to drive the AnimatedContent
animation.
import { useSpring, animated } from 'react-spring'import { Activatable, Box } from '@intouchg/components'import { useMeasure } from '@intouchg/hooks'const AnimatedContent = ({ active, ...props }) => {const [ ref, size ] = useMeasure()const styles = useSpring({ height: active ? size.height : 0 })return (<animated.divstyle={{overflow: 'hidden',willChange: 'height',...styles,}}><Boxref={ref}{...props}/></animated.div>)}const AccordionContent = ({ id, ...props }) => (<Activatable id={id}>{({ active }) => (<AnimatedContentactive={active}{...props}/>)}</Activatable>)export { AccordionContent }
Next we'll create an AccordionContainer
component for basic container styles. This will be the parent element to the AccordionTitle
and AccordionContent
components.
import styled from 'styled-components'import { Stack } from '@intouchg/components'const AccordionContainer = styled(Stack)`width: 100%;background-color: white;border: 2px solid grey;border-radius: 8px;`export { AccordionContainer }
We're finally ready to build some Accordions. Each group of Accordions should be wrapped in an Activatables
component.
Use the AccordionContainer
, AccordionTitle
, and AccordionContent
components to build each Accordion. Remember to pass the
id
prop to the AccordionTitle
and AccordionContent
components.
import { Activatables } from '@intouchg/components'import { AccordionContainer } from './AccordionContainer'import { AccordionTitle } from './AccordionTitle'import { AccordionContent } from './AccordionContent'const MyPage = () => (<ActivatablesallowMultipleActivedefaultActiveIds={[ '1' ]}><AccordionContainer><AccordionTitle id="1">First accordion title</AccordionTitle><AccordionContent id="1">First accordion content - Lorem ipsum dolor sit amet,consectetur adipiscing elit.</AccordionContent></AccordionContainer><AccordionContainer><AccordionTitle id="2">Second accordion title</AccordionTitle><AccordionContent id="2">Second accordion content - Lorem ipsum dolor sit amet,consectetur adipiscing elit.</AccordionContent></AccordionContainer></Activatables>)