Search code examples
reactjsreact-springresize-observerreact-resize-observer

Allow accordion to only open one at a time


I'm creating an Accordion with react spring, the accordion is ready and working fine, but I can not make it to allow the accordion to open one item at the time, right now open all the three item in the same time, I wish to be able to open only one.

here is the codesand -> https://codesandbox.io/s/prod-sun-ttix7?file=/src/App.tsx


Solution

  • You just have to pull up the open state into the App component and and use the key or index as (open) indicator, like this:

    App component

    function App() {
      const [openKey, setOpenKey] = useState()
    
      const handleToggle = key => {
        setOpenKey(openKey !== key ? key : null)
      }
    
      return (
        <Container>
          {data &&
            data.map(({ name, content }) => (
              <ServiceItem
                key={name}
                name={name}
                content={content}
                toggle={handleToggle}
                open={openKey === name}
              />
            ))}
        </Container>
      );
    }
    

    ServiceItem component

    const ServiceItem = ({ name, content, toggle, open }: ServiceItemProps): JSX.Element => {
      return (
        <div key={name}>
          <Item onClick={() => toggle(name)}>
            <Text className="text-15 regular laptop:text-20 laptop:regular">
              {name}
            </Text>
            <Icon className="text-15 regular laptop:text-20 laptop:regular">
              {!open ? "+" : "-"}
            </Icon>
          </Item>
          <Expandable open={open}>
            <ContentContainer>
              <React.Fragment key={name}>
                <Value>{content}</Value>
              </React.Fragment>
            </ContentContainer>
          </Expandable>
        </div>
      );
    };
    

    Here is a working example: https://codesandbox.io/s/infallible-banzai-fnncw.