@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
JavaScript
;
'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]);
}