@react-aria/utils
Advanced tools
Comparing version 3.0.0-nightly.736 to 3.0.0-nightly.738
448
dist/main.js
@@ -14,3 +14,4 @@ var _clsx = $parcel$interopDefault(require("clsx")); | ||
useRef, | ||
useState | ||
useState, | ||
useCallback | ||
} = _react2; | ||
@@ -184,17 +185,114 @@ | ||
exports.mergeProps = mergeProps; | ||
const $a736ffc3e05a0bfc1508098ba395b41$var$DOMPropNames = new Set(['id']); | ||
const $a736ffc3e05a0bfc1508098ba395b41$var$labelablePropNames = new Set(['aria-label', 'aria-labelledby', 'aria-describedby', 'aria-details']); | ||
const $a736ffc3e05a0bfc1508098ba395b41$var$propRe = /^(data-.*)$/; | ||
/** | ||
* Filters out all props that aren't valid DOM props or defined via override prop obj. | ||
* @param props - The component props to be filtered. | ||
* @param opts - Props to override. | ||
*/ | ||
function clamp(value, min, max) { | ||
if (min === void 0) { | ||
min = -Infinity; | ||
function filterDOMProps(props, opts) { | ||
if (opts === void 0) { | ||
opts = {}; | ||
} | ||
if (max === void 0) { | ||
max = Infinity; | ||
let { | ||
labelable, | ||
propNames | ||
} = opts; | ||
let filteredProps = {}; | ||
for (const prop in props) { | ||
if (Object.prototype.hasOwnProperty.call(props, prop) && ($a736ffc3e05a0bfc1508098ba395b41$var$DOMPropNames.has(prop) || labelable && $a736ffc3e05a0bfc1508098ba395b41$var$labelablePropNames.has(prop) || (propNames == null ? void 0 : propNames.has(prop)) || $a736ffc3e05a0bfc1508098ba395b41$var$propRe.test(prop))) { | ||
filteredProps[prop] = props[prop]; | ||
} | ||
} | ||
return Math.min(Math.max(value, min), max); | ||
return filteredProps; | ||
} | ||
exports.clamp = clamp; | ||
exports.filterDOMProps = filterDOMProps; | ||
// Currently necessary for Safari and old Edge: | ||
// https://caniuse.com/#feat=mdn-api_htmlelement_focus_preventscroll_option | ||
// See https://bugs.webkit.org/show_bug.cgi?id=178583 | ||
// | ||
// Original licensing for the following methods can be found in the | ||
// NOTICE file in the root directory of this source tree. | ||
// See https://github.com/calvellido/focus-options-polyfill | ||
function focusWithoutScrolling(element) { | ||
if ($d2a175ba498dd7834499f256dfb330bc$var$supportsPreventScroll()) { | ||
element.focus({ | ||
preventScroll: true | ||
}); | ||
} else { | ||
let scrollableElements = $d2a175ba498dd7834499f256dfb330bc$var$getScrollableElements(element); | ||
element.focus(); | ||
$d2a175ba498dd7834499f256dfb330bc$var$restoreScrollPosition(scrollableElements); | ||
} | ||
} | ||
exports.focusWithoutScrolling = focusWithoutScrolling; | ||
let $d2a175ba498dd7834499f256dfb330bc$var$supportsPreventScrollCached = null; | ||
function $d2a175ba498dd7834499f256dfb330bc$var$supportsPreventScroll() { | ||
if ($d2a175ba498dd7834499f256dfb330bc$var$supportsPreventScrollCached == null) { | ||
$d2a175ba498dd7834499f256dfb330bc$var$supportsPreventScrollCached = false; | ||
try { | ||
var focusElem = document.createElement('div'); | ||
focusElem.focus({ | ||
get preventScroll() { | ||
$d2a175ba498dd7834499f256dfb330bc$var$supportsPreventScrollCached = true; | ||
return true; | ||
} | ||
}); | ||
} catch (e) {// Ignore | ||
} | ||
} | ||
return $d2a175ba498dd7834499f256dfb330bc$var$supportsPreventScrollCached; | ||
} | ||
function $d2a175ba498dd7834499f256dfb330bc$var$getScrollableElements(element) { | ||
var parent = element.parentNode; | ||
var scrollableElements = []; | ||
var rootScrollingElement = document.scrollingElement || document.documentElement; | ||
while (parent instanceof HTMLElement && parent !== rootScrollingElement) { | ||
if (parent.offsetHeight < parent.scrollHeight || parent.offsetWidth < parent.scrollWidth) { | ||
scrollableElements.push({ | ||
element: parent, | ||
scrollTop: parent.scrollTop, | ||
scrollLeft: parent.scrollLeft | ||
}); | ||
} | ||
parent = parent.parentNode; | ||
} | ||
if (rootScrollingElement instanceof HTMLElement) { | ||
scrollableElements.push({ | ||
element: rootScrollingElement, | ||
scrollTop: rootScrollingElement.scrollTop, | ||
scrollLeft: rootScrollingElement.scrollLeft | ||
}); | ||
} | ||
return scrollableElements; | ||
} | ||
function $d2a175ba498dd7834499f256dfb330bc$var$restoreScrollPosition(scrollableElements) { | ||
for (let { | ||
element, | ||
scrollTop, | ||
scrollLeft | ||
} of scrollableElements) { | ||
element.scrollTop = scrollTop; | ||
element.scrollLeft = scrollLeft; | ||
} | ||
} | ||
function getOffset(element, reverse, orientation) { | ||
@@ -215,2 +313,97 @@ if (orientation === void 0) { | ||
exports.getOffset = getOffset; | ||
function clamp(value, min, max) { | ||
if (min === void 0) { | ||
min = -Infinity; | ||
} | ||
if (max === void 0) { | ||
max = Infinity; | ||
} | ||
return Math.min(Math.max(value, min), max); | ||
} | ||
exports.clamp = clamp; | ||
// mapped to a set of CSS properties that are transitioning for that element. | ||
// This is necessary rather than a simple count of transitions because of browser | ||
// bugs, e.g. Chrome sometimes fires both transitionend and transitioncancel rather | ||
// than one or the other. So we need to track what's actually transitioning so that | ||
// we can ignore these duplicate events. | ||
let $a39a8553a97349a69bcc0255658c67ab$var$transitionsByElement = new Map(); // A list of callbacks to call once there are no transitioning elements. | ||
let $a39a8553a97349a69bcc0255658c67ab$var$transitionCallbacks = new Set(); | ||
function $a39a8553a97349a69bcc0255658c67ab$var$setupGlobalEvents() { | ||
if (typeof window === 'undefined') { | ||
return; | ||
} | ||
let onTransitionStart = e => { | ||
// Add the transitioning property to the list for this element. | ||
let transitions = $a39a8553a97349a69bcc0255658c67ab$var$transitionsByElement.get(e.target); | ||
if (!transitions) { | ||
transitions = new Set(); | ||
$a39a8553a97349a69bcc0255658c67ab$var$transitionsByElement.set(e.target, transitions); // The transitioncancel event must be registered on the element itself, rather than as a global | ||
// event. This enables us to handle when the node is deleted from the document while it is transitioning. | ||
// In that case, the cancel event would have nowhere to bubble to so we need to handle it directly. | ||
e.target.addEventListener('transitioncancel', onTransitionEnd); | ||
} | ||
transitions.add(e.propertyName); | ||
}; | ||
let onTransitionEnd = e => { | ||
// Remove property from list of transitioning properties. | ||
let properties = $a39a8553a97349a69bcc0255658c67ab$var$transitionsByElement.get(e.target); | ||
if (!properties) { | ||
return; | ||
} | ||
properties.delete(e.propertyName); // If empty, remove transitioncancel event, and remove the element from the list of transitioning elements. | ||
if (properties.size === 0) { | ||
e.target.removeEventListener('transitioncancel', onTransitionEnd); | ||
$a39a8553a97349a69bcc0255658c67ab$var$transitionsByElement.delete(e.target); | ||
} // If no transitioning elements, call all of the queued callbacks. | ||
if ($a39a8553a97349a69bcc0255658c67ab$var$transitionsByElement.size === 0) { | ||
for (let cb of $a39a8553a97349a69bcc0255658c67ab$var$transitionCallbacks) { | ||
cb(); | ||
} | ||
$a39a8553a97349a69bcc0255658c67ab$var$transitionCallbacks.clear(); | ||
} | ||
}; | ||
document.body.addEventListener('transitionrun', onTransitionStart); | ||
document.body.addEventListener('transitionend', onTransitionEnd); | ||
} | ||
if (typeof document !== 'undefined') { | ||
if (document.readyState !== 'loading') { | ||
$a39a8553a97349a69bcc0255658c67ab$var$setupGlobalEvents(); | ||
} else { | ||
document.addEventListener('DOMContentLoaded', $a39a8553a97349a69bcc0255658c67ab$var$setupGlobalEvents); | ||
} | ||
} | ||
function runAfterTransition(fn) { | ||
// Wait one frame to see if an animation starts, e.g. a transition on mount. | ||
requestAnimationFrame(() => { | ||
// If no transitions are running, call the function immediately. | ||
// Otherwise, add it to a list of callbacks to run at the end of the animation. | ||
if ($a39a8553a97349a69bcc0255658c67ab$var$transitionsByElement.size === 0) { | ||
fn(); | ||
} else { | ||
$a39a8553a97349a69bcc0255658c67ab$var$transitionCallbacks.add(fn); | ||
} | ||
}); | ||
} | ||
exports.runAfterTransition = runAfterTransition; | ||
// Keep track of elements that we are currently handling dragging for via useDrag1D. | ||
@@ -332,5 +525,5 @@ // If there's an ancestor and a descendant both using useDrag1D(), and the user starts | ||
case 'ArrowLeft': | ||
e.preventDefault(); | ||
if (orientation === 'horizontal') { | ||
e.preventDefault(); | ||
if (orientation === 'horizontal') { | ||
if (onDecrement && !reverse) { | ||
@@ -347,5 +540,5 @@ onDecrement(); | ||
case 'ArrowUp': | ||
e.preventDefault(); | ||
if (orientation === 'vertical') { | ||
e.preventDefault(); | ||
if (orientation === 'vertical') { | ||
if (onDecrement && !reverse) { | ||
@@ -362,5 +555,5 @@ onDecrement(); | ||
case 'ArrowRight': | ||
e.preventDefault(); | ||
if (orientation === 'horizontal') { | ||
e.preventDefault(); | ||
if (orientation === 'horizontal') { | ||
if (onIncrement && !reverse) { | ||
@@ -377,5 +570,5 @@ onIncrement(); | ||
case 'ArrowDown': | ||
e.preventDefault(); | ||
if (orientation === 'vertical') { | ||
e.preventDefault(); | ||
if (orientation === 'vertical') { | ||
if (onIncrement && !reverse) { | ||
@@ -429,2 +622,32 @@ onIncrement(); | ||
function useGlobalListeners() { | ||
let globalListeners = useRef(new Map()); | ||
let addGlobalListener = useCallback((eventTarget, type, listener, options) => { | ||
globalListeners.current.set(listener, { | ||
type, | ||
eventTarget, | ||
options | ||
}); | ||
eventTarget.addEventListener(type, listener, options); | ||
}, []); | ||
let removeGlobalListener = useCallback((eventTarget, type, listener, options) => { | ||
eventTarget.removeEventListener(type, listener, options); | ||
globalListeners.current.delete(listener); | ||
}, []); // eslint-disable-next-line arrow-body-style | ||
useEffect(() => { | ||
return () => { | ||
globalListeners.current.forEach((value, key) => { | ||
removeGlobalListener(value.eventTarget, value.type, key, value.options); | ||
}); | ||
}; | ||
}, [removeGlobalListener]); | ||
return { | ||
addGlobalListener, | ||
removeGlobalListener | ||
}; | ||
} | ||
exports.useGlobalListeners = useGlobalListeners; | ||
/** | ||
@@ -481,195 +704,2 @@ * Merges aria-label and aria-labelledby into aria-labelledby when both exist. | ||
// Currently necessary for Safari and old Edge: | ||
// https://caniuse.com/#feat=mdn-api_htmlelement_focus_preventscroll_option | ||
// See https://bugs.webkit.org/show_bug.cgi?id=178583 | ||
// | ||
// Original licensing for the following methods can be found in the | ||
// NOTICE file in the root directory of this source tree. | ||
// See https://github.com/calvellido/focus-options-polyfill | ||
function focusWithoutScrolling(element) { | ||
if ($d2a175ba498dd7834499f256dfb330bc$var$supportsPreventScroll()) { | ||
element.focus({ | ||
preventScroll: true | ||
}); | ||
} else { | ||
let scrollableElements = $d2a175ba498dd7834499f256dfb330bc$var$getScrollableElements(element); | ||
element.focus(); | ||
$d2a175ba498dd7834499f256dfb330bc$var$restoreScrollPosition(scrollableElements); | ||
} | ||
} | ||
exports.focusWithoutScrolling = focusWithoutScrolling; | ||
let $d2a175ba498dd7834499f256dfb330bc$var$supportsPreventScrollCached = null; | ||
function $d2a175ba498dd7834499f256dfb330bc$var$supportsPreventScroll() { | ||
if ($d2a175ba498dd7834499f256dfb330bc$var$supportsPreventScrollCached == null) { | ||
$d2a175ba498dd7834499f256dfb330bc$var$supportsPreventScrollCached = false; | ||
try { | ||
var focusElem = document.createElement('div'); | ||
focusElem.focus({ | ||
get preventScroll() { | ||
$d2a175ba498dd7834499f256dfb330bc$var$supportsPreventScrollCached = true; | ||
return true; | ||
} | ||
}); | ||
} catch (e) {// Ignore | ||
} | ||
} | ||
return $d2a175ba498dd7834499f256dfb330bc$var$supportsPreventScrollCached; | ||
} | ||
function $d2a175ba498dd7834499f256dfb330bc$var$getScrollableElements(element) { | ||
var parent = element.parentNode; | ||
var scrollableElements = []; | ||
var rootScrollingElement = document.scrollingElement || document.documentElement; | ||
while (parent instanceof HTMLElement && parent !== rootScrollingElement) { | ||
if (parent.offsetHeight < parent.scrollHeight || parent.offsetWidth < parent.scrollWidth) { | ||
scrollableElements.push({ | ||
element: parent, | ||
scrollTop: parent.scrollTop, | ||
scrollLeft: parent.scrollLeft | ||
}); | ||
} | ||
parent = parent.parentNode; | ||
} | ||
if (rootScrollingElement instanceof HTMLElement) { | ||
scrollableElements.push({ | ||
element: rootScrollingElement, | ||
scrollTop: rootScrollingElement.scrollTop, | ||
scrollLeft: rootScrollingElement.scrollLeft | ||
}); | ||
} | ||
return scrollableElements; | ||
} | ||
function $d2a175ba498dd7834499f256dfb330bc$var$restoreScrollPosition(scrollableElements) { | ||
for (let { | ||
element, | ||
scrollTop, | ||
scrollLeft | ||
} of scrollableElements) { | ||
element.scrollTop = scrollTop; | ||
element.scrollLeft = scrollLeft; | ||
} | ||
} | ||
const $a736ffc3e05a0bfc1508098ba395b41$var$DOMPropNames = new Set(['id']); | ||
const $a736ffc3e05a0bfc1508098ba395b41$var$labelablePropNames = new Set(['aria-label', 'aria-labelledby', 'aria-describedby', 'aria-details']); | ||
const $a736ffc3e05a0bfc1508098ba395b41$var$propRe = /^(data-.*)$/; | ||
/** | ||
* Filters out all props that aren't valid DOM props or defined via override prop obj. | ||
* @param props - The component props to be filtered. | ||
* @param opts - Props to override. | ||
*/ | ||
function filterDOMProps(props, opts) { | ||
if (opts === void 0) { | ||
opts = {}; | ||
} | ||
let { | ||
labelable, | ||
propNames | ||
} = opts; | ||
let filteredProps = {}; | ||
for (const prop in props) { | ||
if (Object.prototype.hasOwnProperty.call(props, prop) && ($a736ffc3e05a0bfc1508098ba395b41$var$DOMPropNames.has(prop) || labelable && $a736ffc3e05a0bfc1508098ba395b41$var$labelablePropNames.has(prop) || (propNames == null ? void 0 : propNames.has(prop)) || $a736ffc3e05a0bfc1508098ba395b41$var$propRe.test(prop))) { | ||
filteredProps[prop] = props[prop]; | ||
} | ||
} | ||
return filteredProps; | ||
} | ||
exports.filterDOMProps = filterDOMProps; | ||
// mapped to a set of CSS properties that are transitioning for that element. | ||
// This is necessary rather than a simple count of transitions because of browser | ||
// bugs, e.g. Chrome sometimes fires both transitionend and transitioncancel rather | ||
// than one or the other. So we need to track what's actually transitioning so that | ||
// we can ignore these duplicate events. | ||
let $a39a8553a97349a69bcc0255658c67ab$var$transitionsByElement = new Map(); // A list of callbacks to call once there are no transitioning elements. | ||
let $a39a8553a97349a69bcc0255658c67ab$var$transitionCallbacks = new Set(); | ||
function $a39a8553a97349a69bcc0255658c67ab$var$setupGlobalEvents() { | ||
if (typeof window === 'undefined') { | ||
return; | ||
} | ||
let onTransitionStart = e => { | ||
// Add the transitioning property to the list for this element. | ||
let transitions = $a39a8553a97349a69bcc0255658c67ab$var$transitionsByElement.get(e.target); | ||
if (!transitions) { | ||
transitions = new Set(); | ||
$a39a8553a97349a69bcc0255658c67ab$var$transitionsByElement.set(e.target, transitions); // The transitioncancel event must be registered on the element itself, rather than as a global | ||
// event. This enables us to handle when the node is deleted from the document while it is transitioning. | ||
// In that case, the cancel event would have nowhere to bubble to so we need to handle it directly. | ||
e.target.addEventListener('transitioncancel', onTransitionEnd); | ||
} | ||
transitions.add(e.propertyName); | ||
}; | ||
let onTransitionEnd = e => { | ||
// Remove property from list of transitioning properties. | ||
let properties = $a39a8553a97349a69bcc0255658c67ab$var$transitionsByElement.get(e.target); | ||
if (!properties) { | ||
return; | ||
} | ||
properties.delete(e.propertyName); // If empty, remove transitioncancel event, and remove the element from the list of transitioning elements. | ||
if (properties.size === 0) { | ||
e.target.removeEventListener('transitioncancel', onTransitionEnd); | ||
$a39a8553a97349a69bcc0255658c67ab$var$transitionsByElement.delete(e.target); | ||
} // If no transitioning elements, call all of the queued callbacks. | ||
if ($a39a8553a97349a69bcc0255658c67ab$var$transitionsByElement.size === 0) { | ||
for (let cb of $a39a8553a97349a69bcc0255658c67ab$var$transitionCallbacks) { | ||
cb(); | ||
} | ||
$a39a8553a97349a69bcc0255658c67ab$var$transitionCallbacks.clear(); | ||
} | ||
}; | ||
document.body.addEventListener('transitionrun', onTransitionStart); | ||
document.body.addEventListener('transitionend', onTransitionEnd); | ||
} | ||
if (typeof document !== 'undefined') { | ||
if (document.readyState !== 'loading') { | ||
$a39a8553a97349a69bcc0255658c67ab$var$setupGlobalEvents(); | ||
} else { | ||
document.addEventListener('DOMContentLoaded', $a39a8553a97349a69bcc0255658c67ab$var$setupGlobalEvents); | ||
} | ||
} | ||
function runAfterTransition(fn) { | ||
// Wait one frame to see if an animation starts, e.g. a transition on mount. | ||
requestAnimationFrame(() => { | ||
// If no transitions are running, call the function immediately. | ||
// Otherwise, add it to a list of callbacks to run at the end of the animation. | ||
if ($a39a8553a97349a69bcc0255658c67ab$var$transitionsByElement.size === 0) { | ||
fn(); | ||
} else { | ||
$a39a8553a97349a69bcc0255658c67ab$var$transitionCallbacks.add(fn); | ||
} | ||
}); | ||
} | ||
exports.runAfterTransition = runAfterTransition; | ||
function $f58f1969071f2661185e38312efabfc$var$hasResizeObserver() { | ||
@@ -676,0 +706,0 @@ return typeof window.ResizeObserver !== 'undefined'; |
import _clsx from "clsx"; | ||
import { useSSRSafeId } from "@react-aria/ssr"; | ||
import _react, { useEffect, useRef, useState } from "react"; | ||
import _react, { useEffect, useRef, useState, useCallback } from "react"; | ||
// During SSR, React emits a warning when calling useLayoutEffect. | ||
@@ -153,13 +153,109 @@ // Since neither useLayoutEffect nor useEffect run on the server, | ||
} | ||
export function clamp(value, min, max) { | ||
if (min === void 0) { | ||
min = -Infinity; | ||
const $f6a965352cabf1a7c37e8c1337e5eab$var$DOMPropNames = new Set(['id']); | ||
const $f6a965352cabf1a7c37e8c1337e5eab$var$labelablePropNames = new Set(['aria-label', 'aria-labelledby', 'aria-describedby', 'aria-details']); | ||
const $f6a965352cabf1a7c37e8c1337e5eab$var$propRe = /^(data-.*)$/; | ||
/** | ||
* Filters out all props that aren't valid DOM props or defined via override prop obj. | ||
* @param props - The component props to be filtered. | ||
* @param opts - Props to override. | ||
*/ | ||
export function filterDOMProps(props, opts) { | ||
if (opts === void 0) { | ||
opts = {}; | ||
} | ||
if (max === void 0) { | ||
max = Infinity; | ||
let { | ||
labelable, | ||
propNames | ||
} = opts; | ||
let filteredProps = {}; | ||
for (const prop in props) { | ||
if (Object.prototype.hasOwnProperty.call(props, prop) && ($f6a965352cabf1a7c37e8c1337e5eab$var$DOMPropNames.has(prop) || labelable && $f6a965352cabf1a7c37e8c1337e5eab$var$labelablePropNames.has(prop) || (propNames == null ? void 0 : propNames.has(prop)) || $f6a965352cabf1a7c37e8c1337e5eab$var$propRe.test(prop))) { | ||
filteredProps[prop] = props[prop]; | ||
} | ||
} | ||
return Math.min(Math.max(value, min), max); | ||
return filteredProps; | ||
} | ||
// Currently necessary for Safari and old Edge: | ||
// https://caniuse.com/#feat=mdn-api_htmlelement_focus_preventscroll_option | ||
// See https://bugs.webkit.org/show_bug.cgi?id=178583 | ||
// | ||
// Original licensing for the following methods can be found in the | ||
// NOTICE file in the root directory of this source tree. | ||
// See https://github.com/calvellido/focus-options-polyfill | ||
export function focusWithoutScrolling(element) { | ||
if ($bc7c9c3af78f5218ff72cecce15730$var$supportsPreventScroll()) { | ||
element.focus({ | ||
preventScroll: true | ||
}); | ||
} else { | ||
let scrollableElements = $bc7c9c3af78f5218ff72cecce15730$var$getScrollableElements(element); | ||
element.focus(); | ||
$bc7c9c3af78f5218ff72cecce15730$var$restoreScrollPosition(scrollableElements); | ||
} | ||
} | ||
let $bc7c9c3af78f5218ff72cecce15730$var$supportsPreventScrollCached = null; | ||
function $bc7c9c3af78f5218ff72cecce15730$var$supportsPreventScroll() { | ||
if ($bc7c9c3af78f5218ff72cecce15730$var$supportsPreventScrollCached == null) { | ||
$bc7c9c3af78f5218ff72cecce15730$var$supportsPreventScrollCached = false; | ||
try { | ||
var focusElem = document.createElement('div'); | ||
focusElem.focus({ | ||
get preventScroll() { | ||
$bc7c9c3af78f5218ff72cecce15730$var$supportsPreventScrollCached = true; | ||
return true; | ||
} | ||
}); | ||
} catch (e) {// Ignore | ||
} | ||
} | ||
return $bc7c9c3af78f5218ff72cecce15730$var$supportsPreventScrollCached; | ||
} | ||
function $bc7c9c3af78f5218ff72cecce15730$var$getScrollableElements(element) { | ||
var parent = element.parentNode; | ||
var scrollableElements = []; | ||
var rootScrollingElement = document.scrollingElement || document.documentElement; | ||
while (parent instanceof HTMLElement && parent !== rootScrollingElement) { | ||
if (parent.offsetHeight < parent.scrollHeight || parent.offsetWidth < parent.scrollWidth) { | ||
scrollableElements.push({ | ||
element: parent, | ||
scrollTop: parent.scrollTop, | ||
scrollLeft: parent.scrollLeft | ||
}); | ||
} | ||
parent = parent.parentNode; | ||
} | ||
if (rootScrollingElement instanceof HTMLElement) { | ||
scrollableElements.push({ | ||
element: rootScrollingElement, | ||
scrollTop: rootScrollingElement.scrollTop, | ||
scrollLeft: rootScrollingElement.scrollLeft | ||
}); | ||
} | ||
return scrollableElements; | ||
} | ||
function $bc7c9c3af78f5218ff72cecce15730$var$restoreScrollPosition(scrollableElements) { | ||
for (let { | ||
element, | ||
scrollTop, | ||
scrollLeft | ||
} of scrollableElements) { | ||
element.scrollTop = scrollTop; | ||
element.scrollLeft = scrollLeft; | ||
} | ||
} | ||
export function getOffset(element, reverse, orientation) { | ||
@@ -178,2 +274,92 @@ if (orientation === void 0) { | ||
} | ||
export function clamp(value, min, max) { | ||
if (min === void 0) { | ||
min = -Infinity; | ||
} | ||
if (max === void 0) { | ||
max = Infinity; | ||
} | ||
return Math.min(Math.max(value, min), max); | ||
} | ||
// mapped to a set of CSS properties that are transitioning for that element. | ||
// This is necessary rather than a simple count of transitions because of browser | ||
// bugs, e.g. Chrome sometimes fires both transitionend and transitioncancel rather | ||
// than one or the other. So we need to track what's actually transitioning so that | ||
// we can ignore these duplicate events. | ||
let $b3e8d5c5f32fa26afa6df1b81f09b6b8$var$transitionsByElement = new Map(); // A list of callbacks to call once there are no transitioning elements. | ||
let $b3e8d5c5f32fa26afa6df1b81f09b6b8$var$transitionCallbacks = new Set(); | ||
function $b3e8d5c5f32fa26afa6df1b81f09b6b8$var$setupGlobalEvents() { | ||
if (typeof window === 'undefined') { | ||
return; | ||
} | ||
let onTransitionStart = e => { | ||
// Add the transitioning property to the list for this element. | ||
let transitions = $b3e8d5c5f32fa26afa6df1b81f09b6b8$var$transitionsByElement.get(e.target); | ||
if (!transitions) { | ||
transitions = new Set(); | ||
$b3e8d5c5f32fa26afa6df1b81f09b6b8$var$transitionsByElement.set(e.target, transitions); // The transitioncancel event must be registered on the element itself, rather than as a global | ||
// event. This enables us to handle when the node is deleted from the document while it is transitioning. | ||
// In that case, the cancel event would have nowhere to bubble to so we need to handle it directly. | ||
e.target.addEventListener('transitioncancel', onTransitionEnd); | ||
} | ||
transitions.add(e.propertyName); | ||
}; | ||
let onTransitionEnd = e => { | ||
// Remove property from list of transitioning properties. | ||
let properties = $b3e8d5c5f32fa26afa6df1b81f09b6b8$var$transitionsByElement.get(e.target); | ||
if (!properties) { | ||
return; | ||
} | ||
properties.delete(e.propertyName); // If empty, remove transitioncancel event, and remove the element from the list of transitioning elements. | ||
if (properties.size === 0) { | ||
e.target.removeEventListener('transitioncancel', onTransitionEnd); | ||
$b3e8d5c5f32fa26afa6df1b81f09b6b8$var$transitionsByElement.delete(e.target); | ||
} // If no transitioning elements, call all of the queued callbacks. | ||
if ($b3e8d5c5f32fa26afa6df1b81f09b6b8$var$transitionsByElement.size === 0) { | ||
for (let cb of $b3e8d5c5f32fa26afa6df1b81f09b6b8$var$transitionCallbacks) { | ||
cb(); | ||
} | ||
$b3e8d5c5f32fa26afa6df1b81f09b6b8$var$transitionCallbacks.clear(); | ||
} | ||
}; | ||
document.body.addEventListener('transitionrun', onTransitionStart); | ||
document.body.addEventListener('transitionend', onTransitionEnd); | ||
} | ||
if (typeof document !== 'undefined') { | ||
if (document.readyState !== 'loading') { | ||
$b3e8d5c5f32fa26afa6df1b81f09b6b8$var$setupGlobalEvents(); | ||
} else { | ||
document.addEventListener('DOMContentLoaded', $b3e8d5c5f32fa26afa6df1b81f09b6b8$var$setupGlobalEvents); | ||
} | ||
} | ||
export function runAfterTransition(fn) { | ||
// Wait one frame to see if an animation starts, e.g. a transition on mount. | ||
requestAnimationFrame(() => { | ||
// If no transitions are running, call the function immediately. | ||
// Otherwise, add it to a list of callbacks to run at the end of the animation. | ||
if ($b3e8d5c5f32fa26afa6df1b81f09b6b8$var$transitionsByElement.size === 0) { | ||
fn(); | ||
} else { | ||
$b3e8d5c5f32fa26afa6df1b81f09b6b8$var$transitionCallbacks.add(fn); | ||
} | ||
}); | ||
} | ||
// Keep track of elements that we are currently handling dragging for via useDrag1D. | ||
@@ -295,5 +481,5 @@ // If there's an ancestor and a descendant both using useDrag1D(), and the user starts | ||
case 'ArrowLeft': | ||
e.preventDefault(); | ||
if (orientation === 'horizontal') { | ||
e.preventDefault(); | ||
if (orientation === 'horizontal') { | ||
if (onDecrement && !reverse) { | ||
@@ -310,5 +496,5 @@ onDecrement(); | ||
case 'ArrowUp': | ||
e.preventDefault(); | ||
if (orientation === 'vertical') { | ||
e.preventDefault(); | ||
if (orientation === 'vertical') { | ||
if (onDecrement && !reverse) { | ||
@@ -325,5 +511,5 @@ onDecrement(); | ||
case 'ArrowRight': | ||
e.preventDefault(); | ||
if (orientation === 'horizontal') { | ||
e.preventDefault(); | ||
if (orientation === 'horizontal') { | ||
if (onIncrement && !reverse) { | ||
@@ -340,5 +526,5 @@ onIncrement(); | ||
case 'ArrowDown': | ||
e.preventDefault(); | ||
if (orientation === 'vertical') { | ||
e.preventDefault(); | ||
if (orientation === 'vertical') { | ||
if (onIncrement && !reverse) { | ||
@@ -389,3 +575,30 @@ onIncrement(); | ||
} | ||
export function useGlobalListeners() { | ||
let globalListeners = useRef(new Map()); | ||
let addGlobalListener = useCallback((eventTarget, type, listener, options) => { | ||
globalListeners.current.set(listener, { | ||
type, | ||
eventTarget, | ||
options | ||
}); | ||
eventTarget.addEventListener(type, listener, options); | ||
}, []); | ||
let removeGlobalListener = useCallback((eventTarget, type, listener, options) => { | ||
eventTarget.removeEventListener(type, listener, options); | ||
globalListeners.current.delete(listener); | ||
}, []); // eslint-disable-next-line arrow-body-style | ||
useEffect(() => { | ||
return () => { | ||
globalListeners.current.forEach((value, key) => { | ||
removeGlobalListener(value.eventTarget, value.type, key, value.options); | ||
}); | ||
}; | ||
}, [removeGlobalListener]); | ||
return { | ||
addGlobalListener, | ||
removeGlobalListener | ||
}; | ||
} | ||
/** | ||
@@ -436,189 +649,3 @@ * Merges aria-label and aria-labelledby into aria-labelledby when both exist. | ||
} | ||
// Currently necessary for Safari and old Edge: | ||
// https://caniuse.com/#feat=mdn-api_htmlelement_focus_preventscroll_option | ||
// See https://bugs.webkit.org/show_bug.cgi?id=178583 | ||
// | ||
// Original licensing for the following methods can be found in the | ||
// NOTICE file in the root directory of this source tree. | ||
// See https://github.com/calvellido/focus-options-polyfill | ||
export function focusWithoutScrolling(element) { | ||
if ($bc7c9c3af78f5218ff72cecce15730$var$supportsPreventScroll()) { | ||
element.focus({ | ||
preventScroll: true | ||
}); | ||
} else { | ||
let scrollableElements = $bc7c9c3af78f5218ff72cecce15730$var$getScrollableElements(element); | ||
element.focus(); | ||
$bc7c9c3af78f5218ff72cecce15730$var$restoreScrollPosition(scrollableElements); | ||
} | ||
} | ||
let $bc7c9c3af78f5218ff72cecce15730$var$supportsPreventScrollCached = null; | ||
function $bc7c9c3af78f5218ff72cecce15730$var$supportsPreventScroll() { | ||
if ($bc7c9c3af78f5218ff72cecce15730$var$supportsPreventScrollCached == null) { | ||
$bc7c9c3af78f5218ff72cecce15730$var$supportsPreventScrollCached = false; | ||
try { | ||
var focusElem = document.createElement('div'); | ||
focusElem.focus({ | ||
get preventScroll() { | ||
$bc7c9c3af78f5218ff72cecce15730$var$supportsPreventScrollCached = true; | ||
return true; | ||
} | ||
}); | ||
} catch (e) {// Ignore | ||
} | ||
} | ||
return $bc7c9c3af78f5218ff72cecce15730$var$supportsPreventScrollCached; | ||
} | ||
function $bc7c9c3af78f5218ff72cecce15730$var$getScrollableElements(element) { | ||
var parent = element.parentNode; | ||
var scrollableElements = []; | ||
var rootScrollingElement = document.scrollingElement || document.documentElement; | ||
while (parent instanceof HTMLElement && parent !== rootScrollingElement) { | ||
if (parent.offsetHeight < parent.scrollHeight || parent.offsetWidth < parent.scrollWidth) { | ||
scrollableElements.push({ | ||
element: parent, | ||
scrollTop: parent.scrollTop, | ||
scrollLeft: parent.scrollLeft | ||
}); | ||
} | ||
parent = parent.parentNode; | ||
} | ||
if (rootScrollingElement instanceof HTMLElement) { | ||
scrollableElements.push({ | ||
element: rootScrollingElement, | ||
scrollTop: rootScrollingElement.scrollTop, | ||
scrollLeft: rootScrollingElement.scrollLeft | ||
}); | ||
} | ||
return scrollableElements; | ||
} | ||
function $bc7c9c3af78f5218ff72cecce15730$var$restoreScrollPosition(scrollableElements) { | ||
for (let { | ||
element, | ||
scrollTop, | ||
scrollLeft | ||
} of scrollableElements) { | ||
element.scrollTop = scrollTop; | ||
element.scrollLeft = scrollLeft; | ||
} | ||
} | ||
const $f6a965352cabf1a7c37e8c1337e5eab$var$DOMPropNames = new Set(['id']); | ||
const $f6a965352cabf1a7c37e8c1337e5eab$var$labelablePropNames = new Set(['aria-label', 'aria-labelledby', 'aria-describedby', 'aria-details']); | ||
const $f6a965352cabf1a7c37e8c1337e5eab$var$propRe = /^(data-.*)$/; | ||
/** | ||
* Filters out all props that aren't valid DOM props or defined via override prop obj. | ||
* @param props - The component props to be filtered. | ||
* @param opts - Props to override. | ||
*/ | ||
export function filterDOMProps(props, opts) { | ||
if (opts === void 0) { | ||
opts = {}; | ||
} | ||
let { | ||
labelable, | ||
propNames | ||
} = opts; | ||
let filteredProps = {}; | ||
for (const prop in props) { | ||
if (Object.prototype.hasOwnProperty.call(props, prop) && ($f6a965352cabf1a7c37e8c1337e5eab$var$DOMPropNames.has(prop) || labelable && $f6a965352cabf1a7c37e8c1337e5eab$var$labelablePropNames.has(prop) || (propNames == null ? void 0 : propNames.has(prop)) || $f6a965352cabf1a7c37e8c1337e5eab$var$propRe.test(prop))) { | ||
filteredProps[prop] = props[prop]; | ||
} | ||
} | ||
return filteredProps; | ||
} | ||
// mapped to a set of CSS properties that are transitioning for that element. | ||
// This is necessary rather than a simple count of transitions because of browser | ||
// bugs, e.g. Chrome sometimes fires both transitionend and transitioncancel rather | ||
// than one or the other. So we need to track what's actually transitioning so that | ||
// we can ignore these duplicate events. | ||
let $b3e8d5c5f32fa26afa6df1b81f09b6b8$var$transitionsByElement = new Map(); // A list of callbacks to call once there are no transitioning elements. | ||
let $b3e8d5c5f32fa26afa6df1b81f09b6b8$var$transitionCallbacks = new Set(); | ||
function $b3e8d5c5f32fa26afa6df1b81f09b6b8$var$setupGlobalEvents() { | ||
if (typeof window === 'undefined') { | ||
return; | ||
} | ||
let onTransitionStart = e => { | ||
// Add the transitioning property to the list for this element. | ||
let transitions = $b3e8d5c5f32fa26afa6df1b81f09b6b8$var$transitionsByElement.get(e.target); | ||
if (!transitions) { | ||
transitions = new Set(); | ||
$b3e8d5c5f32fa26afa6df1b81f09b6b8$var$transitionsByElement.set(e.target, transitions); // The transitioncancel event must be registered on the element itself, rather than as a global | ||
// event. This enables us to handle when the node is deleted from the document while it is transitioning. | ||
// In that case, the cancel event would have nowhere to bubble to so we need to handle it directly. | ||
e.target.addEventListener('transitioncancel', onTransitionEnd); | ||
} | ||
transitions.add(e.propertyName); | ||
}; | ||
let onTransitionEnd = e => { | ||
// Remove property from list of transitioning properties. | ||
let properties = $b3e8d5c5f32fa26afa6df1b81f09b6b8$var$transitionsByElement.get(e.target); | ||
if (!properties) { | ||
return; | ||
} | ||
properties.delete(e.propertyName); // If empty, remove transitioncancel event, and remove the element from the list of transitioning elements. | ||
if (properties.size === 0) { | ||
e.target.removeEventListener('transitioncancel', onTransitionEnd); | ||
$b3e8d5c5f32fa26afa6df1b81f09b6b8$var$transitionsByElement.delete(e.target); | ||
} // If no transitioning elements, call all of the queued callbacks. | ||
if ($b3e8d5c5f32fa26afa6df1b81f09b6b8$var$transitionsByElement.size === 0) { | ||
for (let cb of $b3e8d5c5f32fa26afa6df1b81f09b6b8$var$transitionCallbacks) { | ||
cb(); | ||
} | ||
$b3e8d5c5f32fa26afa6df1b81f09b6b8$var$transitionCallbacks.clear(); | ||
} | ||
}; | ||
document.body.addEventListener('transitionrun', onTransitionStart); | ||
document.body.addEventListener('transitionend', onTransitionEnd); | ||
} | ||
if (typeof document !== 'undefined') { | ||
if (document.readyState !== 'loading') { | ||
$b3e8d5c5f32fa26afa6df1b81f09b6b8$var$setupGlobalEvents(); | ||
} else { | ||
document.addEventListener('DOMContentLoaded', $b3e8d5c5f32fa26afa6df1b81f09b6b8$var$setupGlobalEvents); | ||
} | ||
} | ||
export function runAfterTransition(fn) { | ||
// Wait one frame to see if an animation starts, e.g. a transition on mount. | ||
requestAnimationFrame(() => { | ||
// If no transitions are running, call the function immediately. | ||
// Otherwise, add it to a list of callbacks to run at the end of the animation. | ||
if ($b3e8d5c5f32fa26afa6df1b81f09b6b8$var$transitionsByElement.size === 0) { | ||
fn(); | ||
} else { | ||
$b3e8d5c5f32fa26afa6df1b81f09b6b8$var$transitionCallbacks.add(fn); | ||
} | ||
}); | ||
} | ||
function $d642970c01dc21e3fe2261c17768$var$hasResizeObserver() { | ||
@@ -625,0 +652,0 @@ return typeof window.ResizeObserver !== 'undefined'; |
import React, { HTMLAttributes, MutableRefObject, EffectCallback, RefObject } from "react"; | ||
import { Orientation, AriaLabelingProps, DOMProps } from "@react-types/shared"; | ||
import { AriaLabelingProps, DOMProps, Orientation } from "@react-types/shared"; | ||
export const useLayoutEffect: typeof React.useLayoutEffect; | ||
@@ -38,7 +38,25 @@ /** | ||
export function mergeProps<T extends Props[]>(...args: T): UnionToIntersection<TupleTypes<T>>; | ||
interface Options { | ||
/** | ||
* If labelling associated aria properties should be included in the filter. | ||
*/ | ||
labelable?: boolean; | ||
/** | ||
* A Set of other property names that should be included in the filter. | ||
*/ | ||
propNames?: Set<string>; | ||
} | ||
/** | ||
* Filters out all props that aren't valid DOM props or defined via override prop obj. | ||
* @param props - The component props to be filtered. | ||
* @param opts - Props to override. | ||
*/ | ||
export function filterDOMProps(props: DOMProps & AriaLabelingProps, opts?: Options): DOMProps & AriaLabelingProps; | ||
export function focusWithoutScrolling(element: HTMLElement): void; | ||
export function getOffset(element: any, reverse: any, orientation?: string): any; | ||
/** | ||
* Takes a value and forces it to the closest min/max. | ||
*/ | ||
export function clamp(value: number, min?: number, max?: number): number; | ||
export function getOffset(element: any, reverse: any, orientation?: string): any; | ||
export function runAfterTransition(fn: () => void): void; | ||
interface UseDrag1DProps { | ||
@@ -58,2 +76,9 @@ containerRef: MutableRefObject<HTMLElement>; | ||
export function useDrag1D(props: UseDrag1DProps): HTMLAttributes<HTMLElement>; | ||
interface GlobalListeners { | ||
addGlobalListener<K extends keyof DocumentEventMap>(el: EventTarget, type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; | ||
addGlobalListener(el: EventTarget, type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; | ||
removeGlobalListener<K extends keyof DocumentEventMap>(el: EventTarget, type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void; | ||
removeGlobalListener(el: EventTarget, type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; | ||
} | ||
export function useGlobalListeners(): GlobalListeners; | ||
/** | ||
@@ -66,20 +91,2 @@ * Merges aria-label and aria-labelledby into aria-labelledby when both exist. | ||
export function useUpdateEffect(effect: EffectCallback, dependencies: any[]): void; | ||
export function focusWithoutScrolling(element: HTMLElement): void; | ||
interface Options { | ||
/** | ||
* If labelling associated aria properties should be included in the filter. | ||
*/ | ||
labelable?: boolean; | ||
/** | ||
* A Set of other property names that should be included in the filter. | ||
*/ | ||
propNames?: Set<string>; | ||
} | ||
/** | ||
* Filters out all props that aren't valid DOM props or defined via override prop obj. | ||
* @param props - The component props to be filtered. | ||
* @param opts - Props to override. | ||
*/ | ||
export function filterDOMProps(props: DOMProps & AriaLabelingProps, opts?: Options): DOMProps & AriaLabelingProps; | ||
export function runAfterTransition(fn: () => void): void; | ||
type useResizeObserverOptionsType<T> = { | ||
@@ -86,0 +93,0 @@ ref: RefObject<T>; |
{ | ||
"name": "@react-aria/utils", | ||
"version": "3.0.0-nightly.736+0ac271ac", | ||
"version": "3.0.0-nightly.738+dc6d7873", | ||
"description": "Spectrum UI components in React", | ||
@@ -21,4 +21,4 @@ "license": "Apache-2.0", | ||
"@babel/runtime": "^7.6.2", | ||
"@react-aria/ssr": "3.0.2-nightly.2414+0ac271ac", | ||
"@react-types/shared": "3.0.0-nightly.736+0ac271ac", | ||
"@react-aria/ssr": "3.0.2-nightly.2416+dc6d7873", | ||
"@react-types/shared": "3.0.0-nightly.738+dc6d7873", | ||
"clsx": "^1.1.1" | ||
@@ -32,3 +32,3 @@ }, | ||
}, | ||
"gitHead": "0ac271ac5508fc6b03e0bd416142aba02546164a" | ||
"gitHead": "dc6d78733fb26fa02afeb1a36e11de7d71c84467" | ||
} |
@@ -16,12 +16,13 @@ /* | ||
export * from './mergeProps'; | ||
export * from './filterDOMProps'; | ||
export * from './focusWithoutScrolling'; | ||
export * from './getOffset'; | ||
export * from './number'; | ||
export * from './getOffset'; | ||
export * from './runAfterTransition'; | ||
export * from './useDrag1D'; | ||
export * from './useGlobalListeners'; | ||
export * from './useLabels'; | ||
export * from './useUpdateEffect'; | ||
export * from './focusWithoutScrolling'; | ||
export * from './filterDOMProps'; | ||
export * from './runAfterTransition'; | ||
export * from './useLayoutEffect'; | ||
export * from './useResizeObserver'; | ||
export * from './getScrollParent'; |
@@ -123,4 +123,4 @@ /* | ||
case 'ArrowLeft': | ||
e.preventDefault(); | ||
if (orientation === 'horizontal') { | ||
e.preventDefault(); | ||
if (onDecrement && !reverse) { | ||
@@ -135,4 +135,4 @@ onDecrement(); | ||
case 'ArrowUp': | ||
e.preventDefault(); | ||
if (orientation === 'vertical') { | ||
e.preventDefault(); | ||
if (onDecrement && !reverse) { | ||
@@ -147,4 +147,4 @@ onDecrement(); | ||
case 'ArrowRight': | ||
e.preventDefault(); | ||
if (orientation === 'horizontal') { | ||
e.preventDefault(); | ||
if (onIncrement && !reverse) { | ||
@@ -159,4 +159,4 @@ onIncrement(); | ||
case 'ArrowDown': | ||
e.preventDefault(); | ||
if (orientation === 'vertical') { | ||
e.preventDefault(); | ||
if (onIncrement && !reverse) { | ||
@@ -163,0 +163,0 @@ onIncrement(); |
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
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
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
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
197383
25
2073