diff --git a/components/src/components/atoms/DynamicPopover/DynamicPopover.tsx b/components/src/components/atoms/DynamicPopover/DynamicPopover.tsx
index 5ab860c7..ee6b1ce5 100644
--- a/components/src/components/atoms/DynamicPopover/DynamicPopover.tsx
+++ b/components/src/components/atoms/DynamicPopover/DynamicPopover.tsx
@@ -2,6 +2,8 @@ import * as React from 'react'
import styled, { css } from 'styled-components'
import { TransitionState, useTransition } from 'react-transition-state'
+import { debounce } from 'lodash'
+
import { mq } from '@/src/utils/responsiveHelpers'
import { Portal } from '../Portal'
@@ -121,6 +123,19 @@ const defaultAnimationFunc: DynamicPopoverAnimationFunc = (
return { translate, mobileTranslate }
}
+const checkRectContainsPoint = (
+ rect?: DOMRect,
+ point?: { x: number; y: number },
+) => {
+ if (!rect || !point) return false
+ return (
+ point.x >= rect.x &&
+ point.x <= rect.x + rect.width &&
+ point.y >= rect.y &&
+ point.y <= rect.y + rect.height
+ )
+}
+
const makeWidth = (width: number | string) =>
typeof width === 'number' ? `${width}px` : width
@@ -201,6 +216,7 @@ const PopoverContainer = styled.div<{
transition: opacity ${$transitionDuration}ms ease-in-out;
top: ${$y}px;
left: ${$x}px;
+ pointer-events: initial;
${$isControlled &&
css`
@@ -358,30 +374,57 @@ export const DynamicPopover = ({
)
}, [_animationFn])
+ // Attach and remove event listeners
React.useEffect(() => {
- setPosition()
-
const handleResize = () => {
setPosition()
}
+ const popoverElement = popoverContainerRef?.current
const targetElement = anchorRef?.current
- let handleMouseEnter: () => void
- let handleMouseLeave: () => void
+ let handleMouseEnter: (e: MouseEvent) => void
+ let handleMouseLeave: (e: MouseEvent) => void
+ let handleMouseMove: (e: MouseEvent) => void
if (!isControlled) {
handleMouseEnter = () => {
- setPosition()
toggle(true)
onShowCallback?.()
}
+ const debouncedMouseMove = debounce(
+ (e: MouseEvent) => {
+ const cursorXY = { x: e.clientX, y: e.clientY }
+ const targetRect = targetElement?.getBoundingClientRect()
+ const popoverRect = popoverElement?.getBoundingClientRect()
+
+ const targetContainsPoint = checkRectContainsPoint(
+ targetRect,
+ cursorXY,
+ )
+ const popoverContainsPoint = checkRectContainsPoint(
+ popoverRect,
+ cursorXY,
+ )
+ if (!targetContainsPoint && !popoverContainsPoint) toggle(false)
+ document.removeEventListener('mousemove', handleMouseMove)
+ },
+ 100,
+ { maxWait: 1000 },
+ )
+
+ handleMouseMove = (e: MouseEvent) => {
+ debouncedMouseMove(e)
+ }
+
handleMouseLeave = () => {
- toggle(false)
+ document.addEventListener('mousemove', handleMouseMove)
}
targetElement?.addEventListener('mouseenter', handleMouseEnter)
targetElement?.addEventListener('mouseleave', handleMouseLeave)
+ popoverElement?.addEventListener('mouseenter', handleMouseEnter)
+ popoverElement?.addEventListener('mouseleave', handleMouseLeave)
}
addEventListener('resize', handleResize)
@@ -390,6 +433,9 @@ export const DynamicPopover = ({
if (!isControlled) {
targetElement?.removeEventListener('mouseenter', handleMouseEnter)
targetElement?.removeEventListener('mouseleave', handleMouseLeave)
+ popoverElement?.removeEventListener('mouseenter', handleMouseEnter)
+ popoverElement?.removeEventListener('mouseleave', handleMouseLeave)
+ document.removeEventListener('mousemove', handleMouseMove)
}
removeEventListener('resize', handleResize)
}
@@ -397,6 +443,7 @@ export const DynamicPopover = ({
placement,
mobilePlacement,
setPosition,
+ positionState,
additionalGap,
onShowCallback,
anchorRef,
diff --git a/components/src/components/molecules/Tooltip/Tooltip.tsx b/components/src/components/molecules/Tooltip/Tooltip.tsx
index 6d0a1ad8..8b185be3 100644
--- a/components/src/components/molecules/Tooltip/Tooltip.tsx
+++ b/components/src/components/molecules/Tooltip/Tooltip.tsx
@@ -78,7 +78,6 @@ const TooltipPopoverElement = styled.div<{
}>(
({ theme, $background, $placement, $mobilePlacement }) => css`
position: relative;
- pointer-events: none;
box-sizing: border-box;
filter: drop-shadow(0px 0px 1px #e8e8e8)
drop-shadow(0px 2px 4px rgba(0, 0, 0, 0.2));
diff --git a/docs/src/reference/mdx/atoms/RecordItem.docs.mdx b/docs/src/reference/mdx/atoms/RecordItem.docs.mdx
index 0de2f149..a1c96a7d 100644
--- a/docs/src/reference/mdx/atoms/RecordItem.docs.mdx
+++ b/docs/src/reference/mdx/atoms/RecordItem.docs.mdx
@@ -8,7 +8,7 @@ import { RecordItem } from '@ensdomains/thorin'
```
```tsx live=true expand=true
-}>user#123
+} value="user#123">user#123
```
## Props
@@ -19,16 +19,16 @@ import { RecordItem } from '@ensdomains/thorin'
```tsx live=true
-
+
0xb794f5ea0ba39494ce839613fffba74279579268
- }>
+ } value="0xb794f5ea0ba39494ce839613fffba74279579268">
0xb794f5ea0ba39494ce839613fffba74279579268
-
+
0xb794...9268
- } inline>
+ } inline value="0xb794f5ea0ba39494ce839613fffba74279579268">
0xb794...9268
@@ -38,16 +38,16 @@ import { RecordItem } from '@ensdomains/thorin'
```tsx live=true
- } size="small">
+ } size="small" value="Small with icon">
Small with icon
- } size="large">
+ } size="large" value="Large with icon">
Large with icon
-
+
Small with label
-
+
Large with label
@@ -57,28 +57,28 @@ import { RecordItem } from '@ensdomains/thorin'
```tsx live=true
- } size="small">
+ } size="small" value="Small with icon">
Small with icon
-
+
Small with label
- } size="large">
+ } size="large" value="Large with icon">
Large with icon
-
+
Large with label
- } inline size="small">
+ } inline size="small" value="Small and inline with icon">
Small and inline with icon
-
+
Small and inline with label
- } inline size="large">
+ } inline size="large" value="Large and inline with icon">
Large and inline with icon
-
+
Large and inline with label