feat: use unified away click hooks

This commit is contained in:
unix
2020-03-25 02:01:13 +08:00
parent f824375374
commit ba0975e71d
3 changed files with 28 additions and 14 deletions

View File

@@ -1,5 +1,6 @@
import React, { MouseEvent, useCallback, useEffect, useMemo, useState } from 'react'
import React, { MouseEvent, useCallback, useMemo, useRef, useState } from 'react'
import useTheme from '../styles/use-theme'
import useClickAway from '../utils/use-click-away'
import { getColor } from './styles'
import ButtonDropdownIcon from './icon'
import ButtonDropdownItem from './item'
@@ -36,6 +37,7 @@ const stopPropagation = (event: MouseEvent<HTMLElement>) => {
const ButtonDropdown: React.FC<React.PropsWithChildren<ButtonDropdownProps>> = React.memo(({
children, type, size, auto, className, disabled, loading, ...props
}) => {
const ref = useRef<HTMLDivElement>(null)
const theme = useTheme()
const colors = getColor(theme.palette, type)
const sizes = getButtonSize(size, auto)
@@ -58,15 +60,11 @@ const ButtonDropdown: React.FC<React.PropsWithChildren<ButtonDropdownProps>> = R
return visible ? colors.hoverBgColor : colors.bgColor
}, [visible, colors, theme.palette])
const closeDetails = () => setVisible(false)
useEffect(() => {
document.addEventListener('click', closeDetails)
return () => document.removeEventListener('click', closeDetails)
}, [])
useClickAway(ref, () => setVisible(false))
return (
<ButtonDropdownContext.Provider value={initialValue}>
<div className={`btn-dropdown ${className}`} onClick={stopPropagation} {...props}>
<div ref={ref} className={`btn-dropdown ${className}`} onClick={stopPropagation} {...props}>
{mainItemChildren}
<details open={visible}>
<summary onClick={clickHandler}>

View File

@@ -1,8 +1,9 @@
import React, { MutableRefObject, useEffect, useMemo, useRef, useState } from 'react'
import React, { MutableRefObject, useMemo, useRef, useState } from 'react'
import useTheme from '../styles/use-theme'
import SelectOption from './select-option'
import SelectIcon from './select-icon'
import Dropdown from '../shared/dropdown'
import useClickAway from '../utils/use-click-away'
import { ZeitUIThemes } from '../styles/themes'
import { SelectContext, SelectConfig } from './select-context'
import { NormalSizes } from '../utils/prop-types'
@@ -79,11 +80,7 @@ const Select: React.FC<React.PropsWithChildren<SelectProps>> = ({
setVisible(!visible)
}
useEffect(() => {
const closeHandler = () => setVisible(false)
document.addEventListener('click', closeHandler)
return () => document.removeEventListener('click', closeHandler)
}, [])
useClickAway(ref, () => setVisible(false))
const selectedChild = useMemo(() => {
const [, optionChildren] = pickChildByProps(children, 'value', value)

View File

@@ -0,0 +1,19 @@
import { MutableRefObject, useEffect } from 'react'
const useClickAway = (
ref: MutableRefObject<HTMLElement | null>,
handler: (event: Event) => void,
) => {
useEffect(() => {
const callback = (event: Event) => {
const el = ref.current
if (!event || !el || el.contains((event as any).target)) return
handler(event)
}
document.addEventListener('click', callback)
return () => document.removeEventListener('click', callback)
}, [ref, handler])
}
export default useClickAway