diff --git a/src/shared/drag.tsx b/src/shared/drag.tsx index eabb53a..5f3d4e6 100644 --- a/src/shared/drag.tsx +++ b/src/shared/drag.tsx @@ -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 } @@ -34,7 +35,17 @@ export function useDrag(translate: Translate, getPointer: (e: StartEvent) => Pos export function useNoDrag(ref: React.MutableRefObject, 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) diff --git a/src/shared/utils.ts b/src/shared/utils.ts new file mode 100644 index 0000000..a950533 --- /dev/null +++ b/src/shared/utils.ts @@ -0,0 +1,32 @@ +export function copyEvent>(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 + } +}