현재 개발 중인 프로젝트에서 dropdown 요소가 재사용이 가능해보여서 시도해보고 있다. 다만 얽힌 요소가 꽤 있어서 열심히 고쳐보고 있다.
드롭다운 요소에 전달되는 데이터는 IGroup
/ IColor
중 하나이다.
export interface IGroup {
id: number;
title: string;
color: string;
}
export interface IColor {
id: number;
color: string;
}
그래서 드롭다운 요소가 둘 중 하나의 데이터를 전달받을 수 있게 설정하고, 데이터가 존재하면 로딩하고 아니면 비워두는 컴포넌트를 작성했다.
import { styled } from "styled-components";
interface DropdownAttrs {
id: number;
title?: string;
color: string;
}
interface DropdownProps<T> {
isUlVisible: boolean;
setIsUlVisible: (x: boolean) => void;
liClickHandler: (event: React.MouseEvent<HTMLElement>) => void;
dataArray: T[];
}
function Dropdown<T extends DropdownAttrs>(props: DropdownProps<T>) {
return (
<Ul visible={props.isUlVisible}>
{props.dataArray.map((data) => (
<Li
key={data.id}
id={data.id.toString()}
onClick={props.liClickHandler}
>
<ColorCircle colorstring={data.color} />
{data.title}
</Li>
))}
</Ul>
);
}
export default Dropdown;
const Ul = styled.ul<{ visible: boolean }>`
display: ${(props) => (props.visible ? "block" : "none")};
list-style: none;
padding: 4px;
position: absolute;
border-radius: 4px;
background-color: #ffffff;
box-shadow: 0px 8px 8px 0px rgba(29, 91, 132, 0.25);
max-width: 160px;
`;
const ColorCircle = styled.div<{ colorstring: string }>`
min-width: 10px;
min-height: 10px;
border-radius: 50%;
background-color: ${(props) => props.colorstring};
margin: 0 11px 0 5px;
`;
const Li = styled.li`
display: flex;
align-items: baseline;
cursor: pointer;
&:hover {
background-color: #cae2fe9c;
}
padding: 3px 5px;
border-radius: 4px;
`;