import { ReactNode, useRef } from 'react'; import styled from '@emotion/styled'; import { useRecoilState } from 'recoil'; import { captureHotkeyTypeInFocusState } from '@/hotkeys/states/captureHotkeyTypeInFocusState'; import { IconChevronDown } from '@/ui/icons/index'; import { overlayBackground, textInputStyle } from '@/ui/themes/effects'; import { useOutsideAlerter } from '../../../hooks/useOutsideAlerter'; type OwnProps = { label: string; isActive: boolean; children?: ReactNode; isUnfolded?: boolean; setIsUnfolded?: React.Dispatch>; resetState?: () => void; }; const StyledDropdownButtonContainer = styled.div` display: flex; flex-direction: column; position: relative; z-index: 1; `; type StyledDropdownButtonProps = { isUnfolded: boolean; isActive: boolean; }; const StyledDropdownButton = styled.div` background: ${({ theme }) => theme.background.primary}; border-radius: 4px; color: ${(props) => (props.isActive ? props.theme.color.blue : 'none')}; cursor: pointer; display: flex; filter: ${(props) => (props.isUnfolded ? 'brightness(0.95)' : 'none')}; padding: ${({ theme }) => theme.spacing(1)}; padding-left: ${({ theme }) => theme.spacing(2)}; padding-right: ${({ theme }) => theme.spacing(2)}; user-select: none; &:hover { filter: brightness(0.95); } `; const StyledDropdown = styled.ul` --outer-border-radius: calc(var(--wraper-border-radius) - 2px); --wraper-border: 1px; --wraper-border-radius: 8px; border: var(--wraper-border) solid ${({ theme }) => theme.border.color.light}; border-radius: var(--wraper-border-radius); display: flex; flex-direction: column; min-width: 160px; padding: 0px; position: absolute; right: 0; top: 14px; ${overlayBackground} li { &:first-of-type { border-top-left-radius: var(--outer-border-radius); border-top-right-radius: var(--outer-border-radius); } &:last-of-type { border-bottom: 0; border-bottom-left-radius: var(--outer-border-radius); border-bottom-right-radius: var(--outer-border-radius); } } `; const StyledDropdownItem = styled.li` align-items: center; border-radius: 2px; color: ${({ theme }) => theme.font.color.secondary}; cursor: pointer; display: flex; margin: 2px; padding: ${({ theme }) => theme.spacing(2)} calc(${({ theme }) => theme.spacing(2)} - 2px); user-select: none; width: calc(160px - ${({ theme }) => theme.spacing(4)}); &:hover { background: ${({ theme }) => theme.background.transparent.light}; } `; const StyledDropdownItemClipped = styled.span` overflow: hidden; text-overflow: ellipsis; white-space: nowrap; `; const StyledDropdownTopOption = styled.li` align-items: center; border-bottom: 1px solid ${({ theme }) => theme.border.color.light}; color: ${({ theme }) => theme.font.color.primary}; cursor: pointer; display: flex; font-size: ${({ theme }) => theme.font.size.sm}; font-weight: ${({ theme }) => theme.font.weight.medium}; justify-content: space-between; padding: calc(${({ theme }) => theme.spacing(2)}) calc(${({ theme }) => theme.spacing(2)}); &:hover { background: ${({ theme }) => theme.background.transparent.light}; } user-select: none; `; const StyledIcon = styled.div` display: flex; justify-content: center; margin-right: ${({ theme }) => theme.spacing(1)}; min-width: ${({ theme }) => theme.spacing(4)}; `; const StyledSearchField = styled.li` align-items: center; border-bottom: var(--wraper-border) solid ${({ theme }) => theme.border.color.light}; color: ${({ theme }) => theme.font.color.secondary}; cursor: pointer; display: flex; font-weight: ${({ theme }) => theme.font.weight.medium}; justify-content: space-between; overflow: hidden; user-select: none; input { border-radius: 8px; box-sizing: border-box; font-family: ${({ theme }) => theme.font.family}; height: 36px; padding: 8px; width: 100%; ${textInputStyle} &:focus { outline: 0 none; } } `; function DropdownButton({ label, isActive, children, isUnfolded = false, setIsUnfolded, resetState, }: OwnProps) { const [, setCaptureHotkeyTypeInFocus] = useRecoilState( captureHotkeyTypeInFocusState, ); const onButtonClick = () => { setIsUnfolded && setIsUnfolded(!isUnfolded); setCaptureHotkeyTypeInFocus((isPreviousUnfolded) => !isPreviousUnfolded); }; const onOutsideClick = () => { setCaptureHotkeyTypeInFocus(false); setIsUnfolded && setIsUnfolded(false); resetState && resetState(); }; const dropdownRef = useRef(null); useOutsideAlerter(dropdownRef, onOutsideClick); return ( {label} {isUnfolded && ( {children} )} ); } const StyleAngleDownContainer = styled.div` color: ${({ theme }) => theme.font.color.tertiary}; display: flex; height: 100%; justify-content: center; margin-left: auto; `; function DropdownTopOptionAngleDown() { return ( ); } DropdownButton.StyledDropdownItem = StyledDropdownItem; DropdownButton.StyledDropdownItemClipped = StyledDropdownItemClipped; DropdownButton.StyledSearchField = StyledSearchField; DropdownButton.StyledDropdownTopOption = StyledDropdownTopOption; DropdownButton.StyledDropdownTopOptionAngleDown = DropdownTopOptionAngleDown; DropdownButton.StyledIcon = StyledIcon; export default DropdownButton;