@react-aria/interactions
Advanced tools
Comparing version 3.0.2 to 3.1.0
@@ -591,3 +591,3 @@ var _babelRuntimeHelpersExtends = $parcel$interopDefault(require("@babel/runtime/helpers/extends")); | ||
// See https://github.com/facebook/react/blob/3c713d513195a53788b3f8bb4b70279d68b15bcc/packages/react-interactions/events/src/dom/shared/index.js#L74-L87 | ||
// Keyboards, Assitive Technologies, and element.click() all produce a "virtual" | ||
// Keyboards, Assistive Technologies, and element.click() all produce a "virtual" | ||
// click event. This is a method of inferring such clicks. Every browser except | ||
@@ -649,2 +649,6 @@ // IE 11 only sets a zero value of "detail" for click events that are "virtual". | ||
/** | ||
* Example, used in components like Dialogs and Popovers so they can close | ||
* when a user clicks outside them. | ||
*/ | ||
function useInteractOutside(props) { | ||
@@ -800,3 +804,6 @@ let { | ||
*/ | ||
// This function wraps a React event handler to make stopPropagation the default, and support continuePropagation instead. | ||
/** | ||
* This function wraps a React event handler to make stopPropagation the default, and support continuePropagation instead. | ||
*/ | ||
function $df2a10e65550e0fb9bbbe4a76eee490$export$createEventHandler(handler) { | ||
@@ -975,3 +982,6 @@ if (!handler) { | ||
} | ||
} // Helper function to determine if a KeyboardEvent is unmodified and could make keyboard focus styles visible | ||
} | ||
/** | ||
* Helper function to determine if a KeyboardEvent is unmodified and could make keyboard focus styles visible. | ||
*/ | ||
@@ -1023,7 +1033,10 @@ | ||
$b83372066b2b4e1d9257843b2455c$var$hasEventBeforeFocus = false; | ||
} // Setup global event listeners to control when keyboard focus style should be visible | ||
} | ||
/** | ||
* Setup global event listeners to control when keyboard focus style should be visible. | ||
*/ | ||
function $b83372066b2b4e1d9257843b2455c$var$setupGlobalFocusEvents() { | ||
if ($b83372066b2b4e1d9257843b2455c$var$hasSetupGlobalListeners) { | ||
if (typeof window === 'undefined' || $b83372066b2b4e1d9257843b2455c$var$hasSetupGlobalListeners) { | ||
return; | ||
@@ -1062,7 +1075,15 @@ } // Programmatic focus() calls shouldn't affect the current input modality. | ||
} | ||
/** | ||
* If true, keyboard focus is visible. | ||
*/ | ||
function isFocusVisible() { | ||
return $b83372066b2b4e1d9257843b2455c$var$currentModality !== 'pointer'; | ||
} | ||
/** | ||
* Keeps state of the current modality. | ||
*/ | ||
exports.isFocusVisible = isFocusVisible; | ||
@@ -1125,3 +1146,51 @@ | ||
exports.useFocusVisible = useFocusVisible; | ||
// iOS fires onPointerEnter twice: once with pointerType="touch" and again with pointerType="mouse". | ||
// We want to ignore these emulated events so they do not trigger hover behavior. | ||
// See https://bugs.webkit.org/show_bug.cgi?id=214609. | ||
let $c4bc39b19aed2151a14d70718d3e34b1$var$globalIgnoreEmulatedMouseEvents = false; | ||
let $c4bc39b19aed2151a14d70718d3e34b1$var$hoverCount = 0; | ||
function $c4bc39b19aed2151a14d70718d3e34b1$var$setGlobalIgnoreEmulatedMouseEvents() { | ||
$c4bc39b19aed2151a14d70718d3e34b1$var$globalIgnoreEmulatedMouseEvents = true; // Clear globalIgnoreEmulatedMouseEvents after a short timeout. iOS fires onPointerEnter | ||
// with pointerType="mouse" immediately after onPointerUp and before onFocus. On other | ||
// devices that don't have this quirk, we don't want to ignore a mouse hover sometime in | ||
// the distant future because a user previously touched the element. | ||
setTimeout(() => { | ||
$c4bc39b19aed2151a14d70718d3e34b1$var$globalIgnoreEmulatedMouseEvents = false; | ||
}, 50); | ||
} | ||
function $c4bc39b19aed2151a14d70718d3e34b1$var$handleGlobalPointerEvent(e) { | ||
if (e.pointerType === 'touch') { | ||
$c4bc39b19aed2151a14d70718d3e34b1$var$setGlobalIgnoreEmulatedMouseEvents(); | ||
} | ||
} | ||
function $c4bc39b19aed2151a14d70718d3e34b1$var$setupGlobalTouchEvents() { | ||
if (typeof document === 'undefined') { | ||
return; | ||
} | ||
if (typeof PointerEvent !== 'undefined') { | ||
document.addEventListener('pointerup', $c4bc39b19aed2151a14d70718d3e34b1$var$handleGlobalPointerEvent); | ||
} else { | ||
document.addEventListener('touchend', $c4bc39b19aed2151a14d70718d3e34b1$var$setGlobalIgnoreEmulatedMouseEvents); | ||
} | ||
$c4bc39b19aed2151a14d70718d3e34b1$var$hoverCount++; | ||
return () => { | ||
$c4bc39b19aed2151a14d70718d3e34b1$var$hoverCount--; | ||
if ($c4bc39b19aed2151a14d70718d3e34b1$var$hoverCount > 0) { | ||
return; | ||
} | ||
if (typeof PointerEvent !== 'undefined') { | ||
document.removeEventListener('pointerup', $c4bc39b19aed2151a14d70718d3e34b1$var$handleGlobalPointerEvent); | ||
} else { | ||
document.removeEventListener('touchend', $c4bc39b19aed2151a14d70718d3e34b1$var$setGlobalIgnoreEmulatedMouseEvents); | ||
} | ||
}; | ||
} | ||
/** | ||
@@ -1131,2 +1200,4 @@ * Handles pointer hover interactions for an element. Normalizes behavior | ||
*/ | ||
function useHover(props) { | ||
@@ -1139,2 +1210,3 @@ let { | ||
} = props; | ||
let [isHovered, setHovered] = useState(false); | ||
let state = useRef({ | ||
@@ -1144,2 +1216,3 @@ isHovered: false, | ||
}).current; | ||
useEffect($c4bc39b19aed2151a14d70718d3e34b1$var$setupGlobalTouchEvents, []); | ||
let hoverProps = useMemo(() => { | ||
@@ -1165,2 +1238,4 @@ let triggerHoverStart = (event, pointerType) => { | ||
} | ||
setHovered(true); | ||
}; | ||
@@ -1187,2 +1262,4 @@ | ||
} | ||
setHovered(false); | ||
}; | ||
@@ -1194,2 +1271,6 @@ | ||
hoverProps.onPointerEnter = e => { | ||
if ($c4bc39b19aed2151a14d70718d3e34b1$var$globalIgnoreEmulatedMouseEvents && e.pointerType === 'mouse') { | ||
return; | ||
} | ||
triggerHoverStart(e, e.pointerType); | ||
@@ -1207,3 +1288,3 @@ }; | ||
hoverProps.onMouseEnter = e => { | ||
if (!state.ignoreEmulatedMouseEvents) { | ||
if (!state.ignoreEmulatedMouseEvents && !$c4bc39b19aed2151a14d70718d3e34b1$var$globalIgnoreEmulatedMouseEvents) { | ||
triggerHoverStart(e, 'mouse'); | ||
@@ -1223,3 +1304,4 @@ } | ||
return { | ||
hoverProps | ||
hoverProps, | ||
isHovered | ||
}; | ||
@@ -1226,0 +1308,0 @@ } |
@@ -568,3 +568,3 @@ import _babelRuntimeHelpersEsmExtends from "@babel/runtime/helpers/esm/extends"; | ||
// See https://github.com/facebook/react/blob/3c713d513195a53788b3f8bb4b70279d68b15bcc/packages/react-interactions/events/src/dom/shared/index.js#L74-L87 | ||
// Keyboards, Assitive Technologies, and element.click() all produce a "virtual" | ||
// Keyboards, Assistive Technologies, and element.click() all produce a "virtual" | ||
// click event. This is a method of inferring such clicks. Every browser except | ||
@@ -626,2 +626,6 @@ // IE 11 only sets a zero value of "detail" for click events that are "virtual". | ||
/** | ||
* Example, used in components like Dialogs and Popovers so they can close | ||
* when a user clicks outside them. | ||
*/ | ||
export function useInteractOutside(props) { | ||
@@ -770,3 +774,6 @@ let { | ||
*/ | ||
// This function wraps a React event handler to make stopPropagation the default, and support continuePropagation instead. | ||
/** | ||
* This function wraps a React event handler to make stopPropagation the default, and support continuePropagation instead. | ||
*/ | ||
function $dc0d75166de722fbf58eb6c3552$export$createEventHandler(handler) { | ||
@@ -938,3 +945,6 @@ if (!handler) { | ||
} | ||
} // Helper function to determine if a KeyboardEvent is unmodified and could make keyboard focus styles visible | ||
} | ||
/** | ||
* Helper function to determine if a KeyboardEvent is unmodified and could make keyboard focus styles visible. | ||
*/ | ||
@@ -986,7 +996,10 @@ | ||
$d01f69bb2ab5f70dfd0005370a2a2cbc$var$hasEventBeforeFocus = false; | ||
} // Setup global event listeners to control when keyboard focus style should be visible | ||
} | ||
/** | ||
* Setup global event listeners to control when keyboard focus style should be visible. | ||
*/ | ||
function $d01f69bb2ab5f70dfd0005370a2a2cbc$var$setupGlobalFocusEvents() { | ||
if ($d01f69bb2ab5f70dfd0005370a2a2cbc$var$hasSetupGlobalListeners) { | ||
if (typeof window === 'undefined' || $d01f69bb2ab5f70dfd0005370a2a2cbc$var$hasSetupGlobalListeners) { | ||
return; | ||
@@ -1025,6 +1038,14 @@ } // Programmatic focus() calls shouldn't affect the current input modality. | ||
} | ||
/** | ||
* If true, keyboard focus is visible. | ||
*/ | ||
export function isFocusVisible() { | ||
return $d01f69bb2ab5f70dfd0005370a2a2cbc$var$currentModality !== 'pointer'; | ||
} | ||
/** | ||
* Keeps state of the current modality. | ||
*/ | ||
export function useInteractionModality() { | ||
@@ -1080,3 +1101,51 @@ $d01f69bb2ab5f70dfd0005370a2a2cbc$var$setupGlobalFocusEvents(); | ||
} | ||
// iOS fires onPointerEnter twice: once with pointerType="touch" and again with pointerType="mouse". | ||
// We want to ignore these emulated events so they do not trigger hover behavior. | ||
// See https://bugs.webkit.org/show_bug.cgi?id=214609. | ||
let $b1a784c66b81d90efa4f74e05b$var$globalIgnoreEmulatedMouseEvents = false; | ||
let $b1a784c66b81d90efa4f74e05b$var$hoverCount = 0; | ||
function $b1a784c66b81d90efa4f74e05b$var$setGlobalIgnoreEmulatedMouseEvents() { | ||
$b1a784c66b81d90efa4f74e05b$var$globalIgnoreEmulatedMouseEvents = true; // Clear globalIgnoreEmulatedMouseEvents after a short timeout. iOS fires onPointerEnter | ||
// with pointerType="mouse" immediately after onPointerUp and before onFocus. On other | ||
// devices that don't have this quirk, we don't want to ignore a mouse hover sometime in | ||
// the distant future because a user previously touched the element. | ||
setTimeout(() => { | ||
$b1a784c66b81d90efa4f74e05b$var$globalIgnoreEmulatedMouseEvents = false; | ||
}, 50); | ||
} | ||
function $b1a784c66b81d90efa4f74e05b$var$handleGlobalPointerEvent(e) { | ||
if (e.pointerType === 'touch') { | ||
$b1a784c66b81d90efa4f74e05b$var$setGlobalIgnoreEmulatedMouseEvents(); | ||
} | ||
} | ||
function $b1a784c66b81d90efa4f74e05b$var$setupGlobalTouchEvents() { | ||
if (typeof document === 'undefined') { | ||
return; | ||
} | ||
if (typeof PointerEvent !== 'undefined') { | ||
document.addEventListener('pointerup', $b1a784c66b81d90efa4f74e05b$var$handleGlobalPointerEvent); | ||
} else { | ||
document.addEventListener('touchend', $b1a784c66b81d90efa4f74e05b$var$setGlobalIgnoreEmulatedMouseEvents); | ||
} | ||
$b1a784c66b81d90efa4f74e05b$var$hoverCount++; | ||
return () => { | ||
$b1a784c66b81d90efa4f74e05b$var$hoverCount--; | ||
if ($b1a784c66b81d90efa4f74e05b$var$hoverCount > 0) { | ||
return; | ||
} | ||
if (typeof PointerEvent !== 'undefined') { | ||
document.removeEventListener('pointerup', $b1a784c66b81d90efa4f74e05b$var$handleGlobalPointerEvent); | ||
} else { | ||
document.removeEventListener('touchend', $b1a784c66b81d90efa4f74e05b$var$setGlobalIgnoreEmulatedMouseEvents); | ||
} | ||
}; | ||
} | ||
/** | ||
@@ -1086,2 +1155,4 @@ * Handles pointer hover interactions for an element. Normalizes behavior | ||
*/ | ||
export function useHover(props) { | ||
@@ -1094,2 +1165,3 @@ let { | ||
} = props; | ||
let [isHovered, setHovered] = useState(false); | ||
let state = useRef({ | ||
@@ -1099,2 +1171,3 @@ isHovered: false, | ||
}).current; | ||
useEffect($b1a784c66b81d90efa4f74e05b$var$setupGlobalTouchEvents, []); | ||
let hoverProps = useMemo(() => { | ||
@@ -1120,2 +1193,4 @@ let triggerHoverStart = (event, pointerType) => { | ||
} | ||
setHovered(true); | ||
}; | ||
@@ -1142,2 +1217,4 @@ | ||
} | ||
setHovered(false); | ||
}; | ||
@@ -1149,2 +1226,6 @@ | ||
hoverProps.onPointerEnter = e => { | ||
if ($b1a784c66b81d90efa4f74e05b$var$globalIgnoreEmulatedMouseEvents && e.pointerType === 'mouse') { | ||
return; | ||
} | ||
triggerHoverStart(e, e.pointerType); | ||
@@ -1162,3 +1243,3 @@ }; | ||
hoverProps.onMouseEnter = e => { | ||
if (!state.ignoreEmulatedMouseEvents) { | ||
if (!state.ignoreEmulatedMouseEvents && !$b1a784c66b81d90efa4f74e05b$var$globalIgnoreEmulatedMouseEvents) { | ||
triggerHoverStart(e, 'mouse'); | ||
@@ -1178,5 +1259,6 @@ } | ||
return { | ||
hoverProps | ||
hoverProps, | ||
isHovered | ||
}; | ||
} | ||
//# sourceMappingURL=module.js.map |
@@ -29,2 +29,6 @@ import React, { HTMLAttributes, RefObject, SyntheticEvent, ReactElement, ReactNode, FocusEvent } from "react"; | ||
} | ||
/** | ||
* Example, used in components like Dialogs and Popovers so they can close | ||
* when a user clicks outside them. | ||
*/ | ||
export function useInteractOutside(props: InteractOutsideProps): void; | ||
@@ -93,3 +97,9 @@ interface PressableProps extends PressProps { | ||
} | ||
/** | ||
* If true, keyboard focus is visible. | ||
*/ | ||
export function isFocusVisible(): boolean; | ||
/** | ||
* Keeps state of the current modality. | ||
*/ | ||
export function useInteractionModality(): Modality; | ||
@@ -107,2 +117,3 @@ /** | ||
hoverProps: HTMLAttributes<HTMLElement>; | ||
isHovered: boolean; | ||
} | ||
@@ -109,0 +120,0 @@ /** |
{ | ||
"name": "@react-aria/interactions", | ||
"version": "3.0.2", | ||
"version": "3.1.0", | ||
"description": "Spectrum UI components in React", | ||
@@ -21,4 +21,4 @@ "license": "Apache-2.0", | ||
"@babel/runtime": "^7.6.2", | ||
"@react-aria/utils": "^3.0.2", | ||
"@react-types/shared": "^3.0.2" | ||
"@react-aria/utils": "^3.1.0", | ||
"@react-types/shared": "^3.1.0" | ||
}, | ||
@@ -31,3 +31,3 @@ "peerDependencies": { | ||
}, | ||
"gitHead": "05003506f02a0ec173f3448f1801cbdf12b47bc7" | ||
"gitHead": "211099972fe75ee581892efd01a7f89dfb9cdf69" | ||
} |
@@ -16,3 +16,5 @@ /* | ||
// This function wraps a React event handler to make stopPropagation the default, and support continuePropagation instead. | ||
/** | ||
* This function wraps a React event handler to make stopPropagation the default, and support continuePropagation instead. | ||
*/ | ||
export function createEventHandler<T extends SyntheticEvent>(handler: (e: BaseEvent<T>) => void): (e: T) => void { | ||
@@ -19,0 +21,0 @@ if (!handler) { |
@@ -57,3 +57,5 @@ /* | ||
// Helper function to determine if a KeyboardEvent is unmodified and could make keyboard focus styles visible | ||
/** | ||
* Helper function to determine if a KeyboardEvent is unmodified and could make keyboard focus styles visible. | ||
*/ | ||
function isValidKey(e: KeyboardEvent) { | ||
@@ -103,5 +105,7 @@ return !(e.metaKey || (!isMac && e.altKey) || e.ctrlKey); | ||
// Setup global event listeners to control when keyboard focus style should be visible | ||
/** | ||
* Setup global event listeners to control when keyboard focus style should be visible. | ||
*/ | ||
function setupGlobalFocusEvents() { | ||
if (hasSetupGlobalListeners) { | ||
if (typeof window === 'undefined' || hasSetupGlobalListeners) { | ||
return; | ||
@@ -141,2 +145,5 @@ } | ||
/** | ||
* If true, keyboard focus is visible. | ||
*/ | ||
export function isFocusVisible(): boolean { | ||
@@ -146,2 +153,5 @@ return currentModality !== 'pointer'; | ||
/** | ||
* Keeps state of the current modality. | ||
*/ | ||
export function useInteractionModality(): Modality { | ||
@@ -148,0 +158,0 @@ setupGlobalFocusEvents(); |
@@ -19,3 +19,3 @@ /* | ||
import {HoverEvents} from '@react-types/shared'; | ||
import {HTMLAttributes, useMemo, useRef} from 'react'; | ||
import {HTMLAttributes, useEffect, useMemo, useRef, useState} from 'react'; | ||
@@ -29,5 +29,56 @@ export interface HoverProps extends HoverEvents { | ||
/** Props to spread on the target element. */ | ||
hoverProps: HTMLAttributes<HTMLElement> | ||
hoverProps: HTMLAttributes<HTMLElement>, | ||
isHovered: boolean | ||
} | ||
// iOS fires onPointerEnter twice: once with pointerType="touch" and again with pointerType="mouse". | ||
// We want to ignore these emulated events so they do not trigger hover behavior. | ||
// See https://bugs.webkit.org/show_bug.cgi?id=214609. | ||
let globalIgnoreEmulatedMouseEvents = false; | ||
let hoverCount = 0; | ||
function setGlobalIgnoreEmulatedMouseEvents() { | ||
globalIgnoreEmulatedMouseEvents = true; | ||
// Clear globalIgnoreEmulatedMouseEvents after a short timeout. iOS fires onPointerEnter | ||
// with pointerType="mouse" immediately after onPointerUp and before onFocus. On other | ||
// devices that don't have this quirk, we don't want to ignore a mouse hover sometime in | ||
// the distant future because a user previously touched the element. | ||
setTimeout(() => { | ||
globalIgnoreEmulatedMouseEvents = false; | ||
}, 50); | ||
} | ||
function handleGlobalPointerEvent(e) { | ||
if (e.pointerType === 'touch') { | ||
setGlobalIgnoreEmulatedMouseEvents(); | ||
} | ||
} | ||
function setupGlobalTouchEvents() { | ||
if (typeof document === 'undefined') { | ||
return; | ||
} | ||
if (typeof PointerEvent !== 'undefined') { | ||
document.addEventListener('pointerup', handleGlobalPointerEvent); | ||
} else { | ||
document.addEventListener('touchend', setGlobalIgnoreEmulatedMouseEvents); | ||
} | ||
hoverCount++; | ||
return () => { | ||
hoverCount--; | ||
if (hoverCount > 0) { | ||
return; | ||
} | ||
if (typeof PointerEvent !== 'undefined') { | ||
document.removeEventListener('pointerup', handleGlobalPointerEvent); | ||
} else { | ||
document.removeEventListener('touchend', setGlobalIgnoreEmulatedMouseEvents); | ||
} | ||
}; | ||
} | ||
/** | ||
@@ -45,2 +96,3 @@ * Handles pointer hover interactions for an element. Normalizes behavior | ||
let [isHovered, setHovered] = useState(false); | ||
let state = useRef({ | ||
@@ -51,2 +103,4 @@ isHovered: false, | ||
useEffect(setupGlobalTouchEvents, []); | ||
let hoverProps = useMemo(() => { | ||
@@ -72,5 +126,6 @@ let triggerHoverStart = (event, pointerType) => { | ||
} | ||
setHovered(true); | ||
}; | ||
let triggerHoverEnd = (event, pointerType) => { | ||
@@ -95,2 +150,4 @@ if (isDisabled || pointerType === 'touch' || !state.isHovered) { | ||
} | ||
setHovered(false); | ||
}; | ||
@@ -102,2 +159,6 @@ | ||
hoverProps.onPointerEnter = (e) => { | ||
if (globalIgnoreEmulatedMouseEvents && e.pointerType === 'mouse') { | ||
return; | ||
} | ||
triggerHoverStart(e, e.pointerType); | ||
@@ -115,3 +176,3 @@ }; | ||
hoverProps.onMouseEnter = (e) => { | ||
if (!state.ignoreEmulatedMouseEvents) { | ||
if (!state.ignoreEmulatedMouseEvents && !globalIgnoreEmulatedMouseEvents) { | ||
triggerHoverStart(e, 'mouse'); | ||
@@ -131,4 +192,5 @@ } | ||
return { | ||
hoverProps | ||
hoverProps, | ||
isHovered | ||
}; | ||
} |
@@ -25,2 +25,6 @@ /* | ||
/** | ||
* Example, used in components like Dialogs and Popovers so they can close | ||
* when a user clicks outside them. | ||
*/ | ||
export function useInteractOutside(props: InteractOutsideProps) { | ||
@@ -27,0 +31,0 @@ let {ref, onInteractOutside} = props; |
@@ -604,3 +604,3 @@ /* | ||
// Keyboards, Assitive Technologies, and element.click() all produce a "virtual" | ||
// Keyboards, Assistive Technologies, and element.click() all produce a "virtual" | ||
// click event. This is a method of inferring such clicks. Every browser except | ||
@@ -611,2 +611,3 @@ // IE 11 only sets a zero value of "detail" for click events that are "virtual". | ||
// where only the "virtual" click lacks a pointerType field. | ||
function isVirtualClick(event: MouseEvent | PointerEvent): boolean { | ||
@@ -613,0 +614,0 @@ // JAWS/NVDA with Firefox. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
331004
3635
Updated@react-aria/utils@^3.1.0
Updated@react-types/shared@^3.1.0