UNPKG

@base-ui-components/react

Version:

Base UI is a library of headless ('unstyled') React components and low-level hooks. You gain complete control over your app's CSS and accessibility features.

75 lines (73 loc) 2.9 kB
"use strict"; 'use client'; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.useClick = useClick; var React = _interopRequireWildcard(require("react")); var _useAnimationFrame = require("@base-ui-components/utils/useAnimationFrame"); var _constants = require("../../utils/constants"); var _utils = require("../utils"); /** * Opens or closes the floating element when clicking the reference element. * @see https://floating-ui.com/docs/useClick */ function useClick(context, props = {}) { const { open, onOpenChange, dataRef } = context; const { enabled = true, event: eventOption = 'click', toggle = true, ignoreMouse = false, stickIfOpen = true } = props; const pointerTypeRef = React.useRef(undefined); const frame = (0, _useAnimationFrame.useAnimationFrame)(); const reference = React.useMemo(() => ({ onPointerDown(event) { pointerTypeRef.current = event.pointerType; }, onMouseDown(event) { const pointerType = pointerTypeRef.current; const nativeEvent = event.nativeEvent; // Ignore all buttons except for the "main" button. // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button if (event.button !== 0 || eventOption === 'click' || (0, _utils.isMouseLikePointerType)(pointerType, true) && ignoreMouse) { return; } const openEvent = dataRef.current.openEvent; const openEventType = openEvent?.type; const nextOpen = !(open && toggle && (openEvent && stickIfOpen ? openEventType === 'click' || openEventType === 'mousedown' : true)); // Wait until focus is set on the element. This is an alternative to // `event.preventDefault()` to avoid :focus-visible from appearing when using a pointer. frame.request(() => { onOpenChange(nextOpen, nativeEvent, 'click'); }); }, onClick(event) { const pointerType = pointerTypeRef.current; if (eventOption === 'mousedown' && pointerType) { pointerTypeRef.current = undefined; return; } if ((0, _utils.isMouseLikePointerType)(pointerType, true) && ignoreMouse) { return; } const openEvent = dataRef.current.openEvent; const openEventType = openEvent?.type; const nextOpen = !(open && toggle && (openEvent && stickIfOpen ? openEventType === 'click' || openEventType === 'mousedown' || openEventType === 'keydown' || openEventType === 'keyup' : true)); onOpenChange(nextOpen, event.nativeEvent, 'click'); }, onKeyDown() { pointerTypeRef.current = undefined; } }), [dataRef, eventOption, ignoreMouse, onOpenChange, open, stickIfOpen, toggle, frame]); return React.useMemo(() => enabled ? { reference } : _constants.EMPTY_OBJECT, [enabled, reference]); }