import React, { HTMLAttributes, MutableRefObject, ReactElement, ReactNode, useCallback } from 'react'; import { isElement } from 'react-is'; import { TStyle, useClassnames } from '../../hooks/use-classnames'; import { Popover, IProps as IPopoverProps } from '../popover'; import { IconMoreVertical } from '../icons/more-vertical'; import { IconArrowsChevronBottom } from '../icons/arrows/chevron-bottom'; import style from './index.module.pcss'; interface ICustomTriggerElement { /** * Левая иконка дропдауна */ elLeftIcon?: ReactElement, /** * Вариант правой иконки дропдауна */ elRightIcon?: 'dots' | 'chevron' | ReactElement, /** * Текст дефолтного триггера */ triggerText?: string } // eslint-disable-next-line @typescript-eslint/no-explicit-any export interface IProps extends Pick, 'style'>, IPopoverProps { /** * Render выпадающего элемента дропдауна **/ readonly render?: ((isOpen: boolean, onClose: () => void, ref: MutableRefObject) => ReactNode | null), /** * Триггер-элемент дропдауна */ readonly triggerElement?: T | ((isOpen: boolean) => T | null), /** * Задает дополнительные CSS классы для стилизации родительского компонента Popover */ readonly popoverClassname?: TStyle | string } export const Dropdown = ({ placement = 'bottom-end', syncOptionsWidth = true, className, ...props }: IProps) => { const cn = useClassnames(style, className); const elRightIconRender = useCallback((isOpen: boolean) => { if(props.triggerElement?.elRightIcon === 'dots') { return ( ); } if(props.triggerElement?.elRightIcon === 'chevron') { return ( ); } return props.triggerElement?.elRightIcon; }, [props.triggerElement?.elRightIcon]); const elTrigger = useCallback((isOpen: boolean) => { if(typeof props.triggerElement === 'function') { return props.triggerElement(isOpen); } if(isElement(props.triggerElement)) { return props.triggerElement; } return (
{props.triggerElement?.elLeftIcon} {props.triggerElement?.triggerText} {elRightIconRender(isOpen)}
); }, [props.triggerElement]); return (
); }; export default Dropdown;