import {useState, useRef, HTMLAttributes, useEffect, CSSProperties} from 'react'; import cls from 'classnames'; import {IconType, Icon} from '@core0/icon'; import {Popover} from '@core0/popover'; import {Transition} from '@core0/transition'; import {Tooltip} from '@core0/tooltip'; import cn from './dropdown.module.styl'; export interface DropdownItem { iconName?: IconType; imgName?: string; text: string; reactKey: string; value: T; tooltip?: string; } export interface DropdownProps extends Pick, 'className' | 'style'> { onActiveItemChange(evt: DropdownItem): void; withArrow?: boolean; placeholder?: string; disabled?: boolean; list: DropdownItem[]; activeItem?: DropdownItem; comparableItem?: DropdownItem; padding?: number; height?: number; roundCorner?: boolean; maxViewableItems?: number; textAlign?: CSSProperties['textAlign']; justifyContent?: CSSProperties['justifyContent']; iconFontSize?: CSSProperties['fontSize']; } export function Dropdown(props: DropdownProps): JSX.Element { const { onActiveItemChange, list, activeItem, comparableItem, className, style, maxViewableItems, textAlign, justifyContent, iconFontSize, withArrow = true, disabled = false, placeholder = 'Please select…', padding = 15, height = 40, roundCorner = false } = props; const hostElmRef = useRef(null); const popoverElmRef = useRef(null); const sortedList: DropdownItem[] = deriveSortedList(); const [popoverAnchorElmDOMRect, setPopoverAnchorElmDOMRect] = useState(); const isPopoverActive = !!popoverAnchorElmDOMRect; const isListEmpty: boolean = list.length === 0; /* **************************************** * Effect Hooks **************************************** */ useEffect(() => { if (!popoverAnchorElmDOMRect || !popoverElmRef.current) return; popoverElmRef.current.style.width = `${popoverAnchorElmDOMRect.width}px`; }, [popoverAnchorElmDOMRect]); /* **************************************** * Event Handlers **************************************** */ function hostElmClickHandler() { if (hostElmRef?.current) { setPopoverAnchorElmDOMRect(hostElmRef.current.getBoundingClientRect()); } } function popoverCloseHandler() { setPopoverAnchorElmDOMRect(undefined); } function dropdownItemClickHandler(item: DropdownItem) { setPopoverAnchorElmDOMRect(undefined); if (item !== activeItem) onActiveItemChange(item); } function deriveSortedList(): DropdownItem[] { const found = list.find((elm) => elm === activeItem); const rest = [...list.filter((elm) => elm !== activeItem)].filter((elm) => elm); return found ? [found, ...rest] : rest; } return ( <>
{!activeItem && placeholder && ( <> {placeholder} {withArrow && } )} {activeItem && ( <> {activeItem?.imgName ? ( activeItem.imgName === 'placeholder' ? ( ) : ( {activeItem.text} ) ) : null} {activeItem?.iconName && ( )} {activeItem?.text && {activeItem?.text}} {withArrow && } )}
{!isListEmpty && isPopoverActive && (
    {sortedList.map((elm, idx) => (
  • dropdownItemClickHandler(elm)} > {elm.imgName ? ( elm.imgName === 'placeholder' ? ( ) : ( {elm.text} ) ) : null} {elm.iconName && ( )} {elm.text && {elm.text}} {elm === activeItem && withArrow && } {elm.tooltip && {elm.tooltip}}
  • ))}
)} ); }