import { useEffect, useState } from "react"; import { css, styled } from "styled-components"; import { Box, BoxProps } from "../Box"; import { Image } from "../Image"; import { ArrowDropDownIcon } from "../Svg"; import { Text } from "../Text"; const DropDownHeader = styled.div` width: 100%; height: 40px; display: flex; align-items: center; padding: 0px 16px; box-shadow: ${({ theme }) => theme.shadows.inset}; border: 1px solid ${({ theme }) => theme.colors.inputSecondary}; border-radius: 16px; background: ${({ theme }) => theme.colors.input}; transition: border-radius 0.15s; `; const DropDownListContainer = styled.div` min-width: 100px; height: 0; position: absolute; overflow: hidden; background: ${({ theme }) => theme.colors.input}; z-index: ${({ theme }) => theme.zIndices.dropdown}; transition: transform 0.15s, opacity 0.15s; transform: scaleY(0); transform-origin: top; opacity: 0; width: 100%; `; const DropDownContainer = styled(Box)<{ isOpen: boolean }>` cursor: pointer; width: 100%; position: relative; background: ${({ theme }) => theme.colors.input}; border-radius: 16px; height: 40px; min-width: 125px; user-select: none; z-index: 20; ${(props) => props.isOpen && css` ${DropDownHeader} { border-bottom: 1px solid ${({ theme }) => theme.colors.inputSecondary}; box-shadow: ${({ theme }) => theme.tooltip.boxShadow}; border-radius: 16px 16px 0 0; } ${DropDownListContainer} { height: auto; transform: scaleY(1); opacity: 1; border: 1px solid ${({ theme }) => theme.colors.inputSecondary}; border-top-width: 0; border-radius: 0 0 16px 16px; box-shadow: ${({ theme }) => theme.tooltip.boxShadow}; } `} svg { position: absolute; right: 16px; top: 50%; transform: translateY(-50%); } `; const DropDownList = styled.ul` padding: 0; margin: 0; box-sizing: border-box; z-index: ${({ theme }) => theme.zIndices.dropdown}; `; const ListItem = styled.li` display: flex; list-style: none; padding: 8px 16px; &:hover { background: ${({ theme }) => theme.colors.inputSecondary}; } `; export interface SelectProps extends BoxProps { options: OptionProps[]; onOptionChange?: (option: OptionProps) => void; placeHolderText?: string; defaultOptionIndex?: number; } export interface OptionProps { label: string; value: any; imageUrl?: string; } const Select: React.FunctionComponent> = ({ options, onOptionChange, defaultOptionIndex = 0, placeHolderText, ...props }) => { const [isOpen, setIsOpen] = useState(false); const [optionSelected, setOptionSelected] = useState(false); const [selectedOptionIndex, setSelectedOptionIndex] = useState(defaultOptionIndex); const toggling = (event: React.MouseEvent) => { setIsOpen(!isOpen); event.stopPropagation(); }; const onOptionClicked = (selectedIndex: number) => (e: React.MouseEvent) => { e.stopPropagation(); setSelectedOptionIndex(selectedIndex); setIsOpen(false); setOptionSelected(true); if (onOptionChange) { onOptionChange(options[selectedIndex]); } }; useEffect(() => { const handleClickOutside = () => { setIsOpen(false); }; document.addEventListener("click", handleClickOutside); return () => { document.removeEventListener("click", handleClickOutside); }; }, []); useEffect(() => { if (defaultOptionIndex) { setSelectedOptionIndex(defaultOptionIndex - 1); setOptionSelected(true); } }, [defaultOptionIndex]); return ( {options?.[selectedOptionIndex]?.imageUrl && ( picked-image )} {!optionSelected && placeHolderText ? placeHolderText : options[selectedOptionIndex]?.label} {options.map((option, index) => placeHolderText || index !== selectedOptionIndex ? ( {option?.imageUrl && ( {`picked-image-${option.label}`} )} {option.label} ) : null )} ); }; export default Select;