mirror of
https://github.com/zhigang1992/react.git
synced 2026-04-24 04:15:54 +08:00
feat: use unified away click hooks
This commit is contained in:
@@ -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}>
|
||||
|
||||
@@ -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)
|
||||
|
||||
19
components/utils/use-click-away.ts
Normal file
19
components/utils/use-click-away.ts
Normal 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
|
||||
Reference in New Issue
Block a user