mirror of
https://github.com/overleaf/overleaf.git
synced 2024-12-14 20:30:56 -05:00
2f803292b4
[web] Clickable share modal buttons GitOrigin-RevId: db6bef9b63e98007741d88b291a282d6ea4a68c5
75 lines
2.3 KiB
TypeScript
75 lines
2.3 KiB
TypeScript
import { useRef, useEffect } from 'react'
|
|
import PolymorphicComponent, {
|
|
PolymorphicComponentProps,
|
|
} from '@/shared/components/polymorphic-component'
|
|
import { MergeAndOverride } from '../../../../types/utils'
|
|
|
|
// Performs a click event on elements that has been clicked,
|
|
// but when releasing the mouse button are no longer hovered
|
|
// by the cursor (which by default cancels the event).
|
|
|
|
type ClickableElementEnhancerOwnProps = {
|
|
onClick: () => void
|
|
onMouseDown?: (e: React.MouseEvent) => void
|
|
offset?: number
|
|
}
|
|
|
|
type ClickableElementEnhancerProps<E extends React.ElementType> =
|
|
MergeAndOverride<
|
|
PolymorphicComponentProps<E>,
|
|
ClickableElementEnhancerOwnProps
|
|
>
|
|
|
|
function ClickableElementEnhancer<E extends React.ElementType>({
|
|
onClick,
|
|
onMouseDown,
|
|
offset = 50, // the offset around the clicked element which should still trigger the click
|
|
...rest
|
|
}: ClickableElementEnhancerProps<E>) {
|
|
const isClickedRef = useRef(false)
|
|
const elRectRef = useRef<DOMRect>()
|
|
const restProps = rest as PolymorphicComponentProps<E>
|
|
|
|
const handleMouseDown = (e: React.MouseEvent) => {
|
|
isClickedRef.current = true
|
|
elRectRef.current = (e.target as HTMLElement).getBoundingClientRect()
|
|
onMouseDown?.(e)
|
|
}
|
|
|
|
useEffect(() => {
|
|
const handleMouseUp = (e: MouseEvent) => {
|
|
if (isClickedRef.current) {
|
|
isClickedRef.current = false
|
|
|
|
if (!elRectRef.current) {
|
|
return
|
|
}
|
|
|
|
const halfWidth = elRectRef.current.width / 2
|
|
const halfHeight = elRectRef.current.height / 2
|
|
|
|
const centerX = elRectRef.current.x + halfWidth
|
|
const centerY = elRectRef.current.y + halfHeight
|
|
|
|
const deltaX = Math.abs(e.clientX - centerX)
|
|
const deltaY = Math.abs(e.clientY - centerY)
|
|
|
|
// Check if the mouse has moved significantly from the element position
|
|
if (deltaX < halfWidth + offset && deltaY < halfHeight + offset) {
|
|
// If the mouse hasn't moved much, consider it a click
|
|
onClick()
|
|
}
|
|
}
|
|
}
|
|
|
|
document.addEventListener('mouseup', handleMouseUp)
|
|
|
|
return () => {
|
|
document.removeEventListener('mouseup', handleMouseUp)
|
|
}
|
|
}, [onClick, offset])
|
|
|
|
return <PolymorphicComponent onMouseDown={handleMouseDown} {...restProps} />
|
|
}
|
|
|
|
export default ClickableElementEnhancer
|