Skip to content

Instantly share code, notes, and snippets.

@felipeorlando
Created January 26, 2021 00:43
Show Gist options
  • Save felipeorlando/5f204803ca61786b8f1c54d313018d33 to your computer and use it in GitHub Desktop.
Save felipeorlando/5f204803ca61786b8f1c54d313018d33 to your computer and use it in GitHub Desktop.
<!-- index -->
import React, { useState } from "react";
import {
StyledBody, StyledContent, StyledHeader, StyledStatusIcon, StyledTitle, StyledWrapper,
} from "./styles";
export interface AccordionProps extends React.HTMLAttributes<HTMLDivElement> {
initialOpened?: boolean;
title: string;
}
const Accordion: React.FC<AccordionProps> = ({ children, initialOpened, title }) => {
const [isOpened, setOpened] = useState(initialOpened || false);
const headerClickHandler = () => {
setOpened(!isOpened);
};
return (
<StyledWrapper>
<StyledHeader onClick={headerClickHandler}>
<StyledTitle>{title}</StyledTitle>
<StyledStatusIcon isOpened={isOpened} />
</StyledHeader>
<StyledContent isActive={isOpened}>
<StyledBody>
{children}
</StyledBody>
</StyledContent>
</StyledWrapper>
);
};
export default Accordion;
<!-- styles -->
import React from "react";
import styled, { css } from "styled-components";
import { ThemeInterface } from "@bitcointrade/theme";
import { default as ArrowDownIcon } from "./arrow-down.svgx";
export const StyledBody = styled.div`
color: ${({ theme }: ThemeInterface) => theme.textColor};
font-size: 1.6rem;
padding: 0 70px 24px 0;
p {
color: ${({ theme }: ThemeInterface) => theme.textColor};
margin: 0;
}
a {
color: ${({ theme }: ThemeInterface) => theme.accentColor};
font-weight: 600;
text-decoration: none;
&:hover {
color: ${({ theme }: ThemeInterface) => theme.accentLightColor};
}
}
p + a {
display: block;
margin-top: 24px;
width: fit-content;
}
`;
interface ContentProps {
isActive: boolean;
}
export const StyledContent = styled.div<ContentProps>`
overflow-y: hidden;
max-height: 0;
transition: max-height 0.5s ease-in-out;
${({ isActive }: ContentProps) => isActive && css`
max-height: 500px;
`}
`;
export const StyledHeader = styled.button`
align-items: center;
background-color: transparent;
border: none;
cursor: pointer;
display: flex;
flex-direction: row;
justify-content: space-between;
outline: none;
width: 100%;
padding: 24px 20px 24px 0;
`;
interface StyledStatusIconProps extends React.SVGAttributes<SVGElement> {
isOpened: boolean;
}
export const StyledStatusIcon = styled(
({ isOpened: _, ...props }: StyledStatusIconProps) => <ArrowDownIcon {...props} />,
)`
color: ${({ theme }: ThemeInterface) => theme.accentColor};
margin-left: 20px;
transition: transform 0.3s ease-in-out;
width: 14px;
${({ isOpened }: StyledStatusIconProps) => isOpened && css`
transform: rotate(180deg);
`}
`;
export const StyledTitle = styled.h4`
color: ${({ theme }: ThemeInterface) => theme.textColor};
font-weight: 600;
text-align: left;
width: calc(100% - 30px);
`;
export const StyledWrapper = styled.div`
border-bottom: 2px solid ${({ theme }: ThemeInterface) => theme.boundaryColor};
`;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment