Skip to content

Commit

Permalink
fix: filter click events within portal elements
Browse files Browse the repository at this point in the history
  • Loading branch information
koba04 committed Sep 10, 2020
1 parent 9e87ca5 commit 5931920
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 8 deletions.
9 changes: 3 additions & 6 deletions src/components/Dropdown/Dropdown.tsx
Expand Up @@ -10,7 +10,7 @@ import React, {
} from 'react'
import { createPortal } from 'react-dom'

import { Rect, hasParentElement } from './dropdownHelper'
import { Rect, createPortalElement, isElementInPortal } from './dropdownHelper'

type Props = {
children: ReactNode
Expand Down Expand Up @@ -44,16 +44,13 @@ export const Dropdown: FC<Props> = ({ children }) => {
const [active, setActive] = useState(false)
const [triggerRect, setTriggerRect] = useState<Rect>(initialRect)

const portalElementRef = useRef(document.createElement('div'))
const portalElementRef = useRef(createPortalElement())
const triggerElementRef = useRef<HTMLDivElement>(null)

useEffect(() => {
const onClickBody = (e: any) => {
// ignore events from events within DropdownTrigger and DropdownContent
if (
e.target === triggerElementRef.current ||
hasParentElement(e.target, portalElementRef.current)
) {
if (e.target === triggerElementRef.current || isElementInPortal(e.target)) {
return
}
setActive(false)
Expand Down
12 changes: 10 additions & 2 deletions src/components/Dropdown/dropdownHelper.ts
Expand Up @@ -5,9 +5,17 @@ export type Rect = {
left: number
}

export function hasParentElement(element: HTMLElement | null, parent: HTMLElement | null): boolean {
export const PORTAL_CLASSNAME = '__dropdown--portal--root__'

export function createPortalElement() {
const element = document.createElement('div')
element.className = PORTAL_CLASSNAME
return element
}

export function isElementInPortal(element: HTMLElement | null): boolean {
if (!element) return false
return element === parent || hasParentElement(element.parentElement, parent)
return element.className === PORTAL_CLASSNAME || isElementInPortal(element.parentElement)
}

type Size = { width: number; height: number }
Expand Down

0 comments on commit 5931920

Please sign in to comment.