| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- import { isDragActive } from '../drag/state/is-active.mjs';
- import { isNodeOrChild } from '../utils/is-node-or-child.mjs';
- import { isPrimaryPointer } from '../utils/is-primary-pointer.mjs';
- import { setupGesture } from '../utils/setup.mjs';
- import { isElementKeyboardAccessible } from './utils/is-keyboard-accessible.mjs';
- import { enableKeyboardPress } from './utils/keyboard.mjs';
- import { isPressing } from './utils/state.mjs';
- /**
- * Filter out events that are not primary pointer events, or are triggering
- * while a Motion gesture is active.
- */
- function isValidPressEvent(event) {
- return isPrimaryPointer(event) && !isDragActive();
- }
- /**
- * Create a press gesture.
- *
- * Press is different to `"pointerdown"`, `"pointerup"` in that it
- * automatically filters out secondary pointer events like right
- * click and multitouch.
- *
- * It also adds accessibility support for keyboards, where
- * an element with a press gesture will receive focus and
- * trigger on Enter `"keydown"` and `"keyup"` events.
- *
- * This is different to a browser's `"click"` event, which does
- * respond to keyboards but only for the `"click"` itself, rather
- * than the press start and end/cancel. The element also needs
- * to be focusable for this to work, whereas a press gesture will
- * make an element focusable by default.
- *
- * @public
- */
- function press(targetOrSelector, onPressStart, options = {}) {
- const [targets, eventOptions, cancelEvents] = setupGesture(targetOrSelector, options);
- const startPress = (startEvent) => {
- const target = startEvent.currentTarget;
- if (!isValidPressEvent(startEvent) || isPressing.has(target))
- return;
- isPressing.add(target);
- const onPressEnd = onPressStart(target, startEvent);
- const onPointerEnd = (endEvent, success) => {
- window.removeEventListener("pointerup", onPointerUp);
- window.removeEventListener("pointercancel", onPointerCancel);
- if (!isValidPressEvent(endEvent) || !isPressing.has(target)) {
- return;
- }
- isPressing.delete(target);
- if (typeof onPressEnd === "function") {
- onPressEnd(endEvent, { success });
- }
- };
- const onPointerUp = (upEvent) => {
- onPointerEnd(upEvent, target === window ||
- target === document ||
- options.useGlobalTarget ||
- isNodeOrChild(target, upEvent.target));
- };
- const onPointerCancel = (cancelEvent) => {
- onPointerEnd(cancelEvent, false);
- };
- window.addEventListener("pointerup", onPointerUp, eventOptions);
- window.addEventListener("pointercancel", onPointerCancel, eventOptions);
- };
- targets.forEach((target) => {
- const pointerDownTarget = options.useGlobalTarget ? window : target;
- pointerDownTarget.addEventListener("pointerdown", startPress, eventOptions);
- if (target instanceof HTMLElement) {
- target.addEventListener("focus", (event) => enableKeyboardPress(event, eventOptions));
- if (!isElementKeyboardAccessible(target) &&
- !target.hasAttribute("tabindex")) {
- target.tabIndex = 0;
- }
- }
- });
- return cancelEvents;
- }
- export { press };
|