import React, { MouseEvent, useCallback, useMemo, useRef, useState } from 'react' import useTheme from '../use-theme' import useClickAway from '../utils/use-click-away' import { getColor } from './styles' import ButtonDropdownIcon from './icon' import ButtonDropdownItem from './button-dropdown-item' import { ButtonDropdownContext } from './button-dropdown-context' import { NormalTypes } from '../utils/prop-types' import { pickChild, pickChildByProps } from '../utils/collections' import useScale, { withScale } from '../use-scale' import useClasses from '../use-classes' export type ButtonDropdownTypes = NormalTypes interface Props { type?: ButtonDropdownTypes auto?: boolean loading?: boolean disabled?: boolean className?: string icon?: React.ReactNode } const defaultProps = { type: 'default' as ButtonDropdownTypes, auto: false, loading: false, disabled: false, className: '' } type NativeAttrs = Omit, keyof Props> export type ButtonDropdownProps = Props & NativeAttrs const stopPropagation = (event: MouseEvent) => { event.stopPropagation() event.nativeEvent.stopImmediatePropagation() } const ButtonDropdownComponent: React.FC> = ({ children, type, auto, className, disabled, loading, icon, ...props }) => { const { SCALES } = useScale() const ref = useRef(null) const theme = useTheme() const colors = getColor(theme.palette, type) const itemChildren = pickChild(children, ButtonDropdownItem)[1] const [itemChildrenWithoutMain, mainItemChildren] = pickChildByProps(itemChildren, 'main', true) const [visible, setVisible] = useState(false) const clickHandler = useCallback( (event: MouseEvent) => { event.preventDefault() stopPropagation(event) if (disabled || loading) return setVisible(!visible) }, [visible] ) const initialValue = { type, auto, disabled, loading } const bgColor = useMemo(() => { if (disabled || loading) return theme.palette.accents_1 return visible ? colors.hoverBgColor : colors.bgColor }, [visible, colors, theme.palette]) const [paddingLeft, paddingRight] = [ auto ? SCALES.pl(1.15) : SCALES.pl(1.375), auto ? SCALES.pr(1.15) : SCALES.pr(1.375) ] useClickAway(ref, () => setVisible(false)) return (
{mainItemChildren}
{icon ? ( {icon} ) : ( )}
{itemChildrenWithoutMain}
) } ButtonDropdownComponent.displayName = 'HuiButtonDropdown' ButtonDropdownComponent.defaultProps = defaultProps const ButtonDropdown = withScale(ButtonDropdownComponent) export default ButtonDropdown