import React, { useState, useEffect, useCallback } from "react"; import Icon, { IconName, IconSize } from "./Icon"; import { CommonComponentProps, Classes } from "./common"; import styled from "styled-components"; import Text, { TextType } from "./Text"; type DropdownOption = { label?: string; value: string; id?: string; icon?: IconName; onSelect?: (option: DropdownOption) => void; children?: DropdownOption[]; }; type DropdownProps = CommonComponentProps & { options: DropdownOption[]; selected: DropdownOption; }; const DropdownContainer = styled.div` width: 260px; `; const Selected = styled.div<{ isOpen: boolean; disabled?: boolean }>` padding: ${props => props.theme.spaces[4]}px ${props => props.theme.spaces[6]}px; background: ${props => props.disabled ? props.theme.colors.dropdown.header.disabledText : props.theme.colors.dropdown.header.disabledBg}; display: flex; align-items: center; justify-content: space-between; width: 100%; cursor: pointer; ${props => props.isOpen && !props.disabled ? `border: 1.2px solid ${props.theme.colors.info.main}` : null}; ${props => props.isOpen && !props.disabled ? "box-sizing: border-box" : null}; ${props => props.isOpen && !props.disabled ? "box-shadow: 0px 0px 4px 4px rgba(203, 72, 16, 0.18)" : null}; .${Classes.TEXT} { ${props => props.disabled ? `color: ${props.theme.colors.dropdown.text}` : `color: ${props.theme.colors.dropdown.disabledText}`}; } `; const DropdownWrapper = styled.div` margin-top: ${props => props.theme.spaces[2] - 1}px; background: ${props => props.theme.colors.dropdown.menuBg}; box-shadow: 0px 12px 28px ${props => props.theme.colors.dropdown.menuShadow}; width: 100%; `; const OptionWrapper = styled.div<{ selected: boolean }>` padding: ${props => props.theme.spaces[4]}px ${props => props.theme.spaces[6]}px; cursor: pointer; display: flex; align-items: center; ${props => props.selected ? `background: ${props.theme.colors.dropdown.selected.bg}` : null}; .${Classes.TEXT} { ${props => props.selected ? `color: ${props.theme.colors.dropdown.selected.text}` : null}; } .${Classes.ICON} { margin-right: ${props => props.theme.spaces[5]}px; svg { path { ${props => props.selected ? `fill: ${props.theme.colors.dropdown.selected.icon}` : `fill: ${props.theme.colors.dropdown.icon}`}; } } } &:hover { .${Classes.TEXT} { color: ${props => props.theme.colors.dropdown.selected.text}; } .${Classes.ICON} { svg { path { fill: ${props => props.theme.colors.dropdown.selected.icon}; } } } } `; const LabelWrapper = styled.div<{ label?: string }>` display: flex; flex-direction: column; align-items: flex-start; ${props => props.label ? ` .${Classes.TEXT}:last-child { margin-top: ${props.theme.spaces[2] - 1}px; } ` : null} `; export default function Dropdown(props: DropdownProps) { const [isOpen, setIsOpen] = useState(false); const [selected, setSelected] = useState(props.selected); useEffect(() => { setSelected(props.selected); }, [props.selected]); const optionClickHandler = useCallback((option: DropdownOption) => { setSelected(option); setIsOpen(false); option.onSelect && option.onSelect(option); }, []); return ( setIsOpen(false)} data-cy={props.cypressSelector} > setIsOpen(!isOpen)} > {selected.value} {isOpen && !props.disabled ? ( {props.options.map((option: DropdownOption, index: number) => { return ( optionClickHandler(option)} > {option.icon ? ( ) : null} {option.label ? ( {option.value} ) : ( {option.value} )} {option.label ? ( {option.label} ) : null} ); })} ) : null} ); }