Created
September 24, 2021 10:23
-
-
Save rajasegar/9628b5d3489d6270c6c1b5c35ba5f81f to your computer and use it in GitHub Desktop.
Accordion component in React and Typescript using details and summary
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useState } from "react"; | |
import styled from "styled-components"; | |
import { Icons } from "../Icons"; | |
const Content = styled.div` | |
padding: 1em; | |
`; | |
const Summary = styled.summary` | |
::marker { | |
display: none; | |
} | |
`; | |
export function Option({ label, children }) { | |
const [open, setOpen] = useState(false); | |
return ( | |
<React.Fragment> | |
<Summary onClick={() => setOpen(!open)}> | |
<div | |
style={{ | |
display: "flex", | |
justifyContent: "space-between", | |
alignItems: "center", | |
}} | |
> | |
<div> {label} </div> | |
<div> | |
<Icons glyph={open ? "chevron-up" : "chevron-down"} /> | |
</div> | |
</div> | |
</Summary> | |
<Content>{children}</Content> | |
</React.Fragment> | |
); | |
} | |
const AccordionWrapper = styled.div` | |
summary::moz-details-marker { | |
display: none; | |
} | |
summary::webkit-details-marker { | |
display: none; | |
} | |
`; | |
export const AccordionItem = styled.details.attrs((props) => ({ | |
open: props.open || false, | |
}))` | |
background-color: white; | |
padding: 0.5em; | |
border-top: 1px solid #eee; | |
border-bottom: 1px solid #eee; | |
font-style: inherit; | |
:hover { | |
box-shadow: 1px 1px 16px rgba(0, 0, 0, 0.25); | |
} | |
summary::-webkit-details-marker, | |
summary::marker { | |
display: none; | |
content: ""; | |
} | |
`; | |
type AccordionProps = { | |
children: React.ReactNode; | |
}; | |
export function Accordion({ children }: AccordionProps) { | |
return <AccordionWrapper>{children}</AccordionWrapper>; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from "react"; | |
import { AccordionItem, Option, Accordion } from "./"; | |
export const Basic = () => { | |
const openSections = [1]; | |
function getContent(text) { | |
return <div>{text}</div>; | |
} | |
function getOptions(openSections) { | |
return []; | |
} | |
return ( | |
<> | |
<Accordion> | |
<AccordionItem open={true}> | |
<Option label="Section Title One">{getContent("Lorem ipsum")}</Option> | |
</AccordionItem> | |
<AccordionItem> | |
<Option label="Section Title Two">{getContent("Lorem ipsum")}</Option> | |
</AccordionItem> | |
<AccordionItem> | |
<Option label="Section Title Three"> | |
{getContent("Lorem ipsum")} | |
</Option> | |
</AccordionItem> | |
</Accordion> | |
</> | |
); | |
}; | |
export default { | |
component: Basic, | |
title: "Accordion", | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment