Skip to content

Commit 7c2e756

Browse files
authored
Merge pull request #43 from retejs/fix/no-drag-for-radix-ui
fix: pointerdown propagation
2 parents 7e4d3da + 14ae6ec commit 7c2e756

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

src/shared/drag.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as React from 'react'
22

33
import { Position } from '../types'
4+
import { copyEvent, findReactRoot } from './utils'
45

56
type Translate = (dx: number, dy: number) => void
67
type StartEvent = { pageX: number, pageY: number }
@@ -34,7 +35,17 @@ export function useDrag(translate: Translate, getPointer: (e: StartEvent) => Pos
3435

3536
export function useNoDrag(ref: React.MutableRefObject<HTMLElement | null>, disabled?: boolean) {
3637
React.useEffect(() => {
37-
const handleClick = (e: PointerEvent) => !disabled && e.stopPropagation()
38+
const handleClick = (e: PointerEvent) => {
39+
if (disabled) return
40+
41+
const root = findReactRoot(e.target as HTMLElement)
42+
const target = React.version.startsWith('16') ? document : root
43+
44+
if (target) {
45+
e.stopPropagation()
46+
target.dispatchEvent(copyEvent(e))
47+
}
48+
}
3849
const el = ref.current
3950

4051
el?.addEventListener('pointerdown', handleClick)

src/shared/utils.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
export function copyEvent<T extends Event & Record<string, any>>(e: T) {
2+
const newEvent = new (e.constructor as { new(type: string): T })(e.type)
3+
let current = newEvent
4+
5+
while ((current = Object.getPrototypeOf(current))) {
6+
const keys = Object.getOwnPropertyNames(current)
7+
8+
for (const k of keys) {
9+
const item = newEvent[k]
10+
11+
if (typeof item === 'function') continue
12+
13+
Object.defineProperty(newEvent, k, { value: e[k] })
14+
}
15+
}
16+
17+
return newEvent
18+
}
19+
20+
const rootPrefix = '__reactContainer$'
21+
22+
type Keys = `${typeof rootPrefix}${string}` | '_reactRootContainer'
23+
type ReactNode = { [key in Keys]?: unknown } & HTMLElement
24+
25+
export function findReactRoot(element: HTMLElement) {
26+
let current: ReactNode | null = element as ReactNode
27+
28+
while (current) {
29+
if (current._reactRootContainer || Object.keys(current).some(key => key.startsWith(rootPrefix))) return current
30+
current = current.parentElement as ReactNode
31+
}
32+
}

0 commit comments

Comments
 (0)