Skip to content

Commit

Permalink
Merge pull request #43 from retejs/fix/no-drag-for-radix-ui
Browse files Browse the repository at this point in the history
fix: pointerdown propagation
  • Loading branch information
Ni55aN authored Oct 5, 2023
2 parents 7e4d3da + 14ae6ec commit 7c2e756
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 1 deletion.
13 changes: 12 additions & 1 deletion src/shared/drag.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react'

import { Position } from '../types'
import { copyEvent, findReactRoot } from './utils'

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

export function useNoDrag(ref: React.MutableRefObject<HTMLElement | null>, disabled?: boolean) {
React.useEffect(() => {
const handleClick = (e: PointerEvent) => !disabled && e.stopPropagation()
const handleClick = (e: PointerEvent) => {
if (disabled) return

const root = findReactRoot(e.target as HTMLElement)
const target = React.version.startsWith('16') ? document : root

if (target) {
e.stopPropagation()
target.dispatchEvent(copyEvent(e))
}
}
const el = ref.current

el?.addEventListener('pointerdown', handleClick)
Expand Down
32 changes: 32 additions & 0 deletions src/shared/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
export function copyEvent<T extends Event & Record<string, any>>(e: T) {
const newEvent = new (e.constructor as { new(type: string): T })(e.type)
let current = newEvent

while ((current = Object.getPrototypeOf(current))) {
const keys = Object.getOwnPropertyNames(current)

for (const k of keys) {
const item = newEvent[k]

if (typeof item === 'function') continue

Object.defineProperty(newEvent, k, { value: e[k] })
}
}

return newEvent
}

const rootPrefix = '__reactContainer$'

type Keys = `${typeof rootPrefix}${string}` | '_reactRootContainer'
type ReactNode = { [key in Keys]?: unknown } & HTMLElement

export function findReactRoot(element: HTMLElement) {
let current: ReactNode | null = element as ReactNode

while (current) {
if (current._reactRootContainer || Object.keys(current).some(key => key.startsWith(rootPrefix))) return current
current = current.parentElement as ReactNode
}
}

0 comments on commit 7c2e756

Please sign in to comment.