Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@react-aria/overlays

Package Overview
Dependencies
Maintainers
1
Versions
790
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@react-aria/overlays - npm Package Compare versions

Comparing version 3.0.0-nightly.767 to 3.0.0-nightly.770

src/ariaHideOutside.ts

157

dist/main.js

@@ -32,2 +32,3 @@ var {

useEffect,
useRef,
useState,

@@ -77,4 +78,6 @@ useLayoutEffect,

};
const $c13020473a0fe27b1a1c4797269d1704$var$PARSED_PLACEMENT_CACHE = {};
const $c13020473a0fe27b1a1c4797269d1704$var$PARSED_PLACEMENT_CACHE = {}; // @ts-ignore
let $c13020473a0fe27b1a1c4797269d1704$var$visualViewport = typeof window !== 'undefined' && window.visualViewport;
function $c13020473a0fe27b1a1c4797269d1704$var$getContainerDimensions(containerNode) {

@@ -88,4 +91,6 @@ let width = 0,

if (containerNode.tagName === 'BODY') {
width = document.documentElement.clientWidth;
height = document.documentElement.clientHeight;
var _visualViewport$width, _visualViewport$heigh;
width = (_visualViewport$width = $c13020473a0fe27b1a1c4797269d1704$var$visualViewport == null ? void 0 : $c13020473a0fe27b1a1c4797269d1704$var$visualViewport.width) != null ? _visualViewport$width : document.documentElement.clientWidth;
height = (_visualViewport$heigh = $c13020473a0fe27b1a1c4797269d1704$var$visualViewport == null ? void 0 : $c13020473a0fe27b1a1c4797269d1704$var$visualViewport.height) != null ? _visualViewport$heigh : document.documentElement.clientHeight;
scroll.top = _domHelpersQueryScrollTop(_domHelpersOwnerDocument(containerNode).documentElement) || _domHelpersQueryScrollTop(containerNode);

@@ -371,2 +376,4 @@ scroll.left = _domHelpersQueryScrollLeft(_domHelpersOwnerDocument(containerNode).documentElement) || _domHelpersQueryScrollLeft(containerNode);

// @ts-ignore
let $adfbd034e9bc71c1$var$visualViewport = typeof window !== 'undefined' && window.visualViewport;
/**

@@ -376,2 +383,3 @@ * Handles positioning overlays like popovers and menus relative to a trigger

*/
function useOverlayPosition(props) {

@@ -423,3 +431,28 @@ let {

$adfbd034e9bc71c1$var$useResize(updatePosition); // When scrolling a parent scrollable region of the trigger (other than the body),
$adfbd034e9bc71c1$var$useResize(updatePosition); // Reposition the overlay and do not close on scroll while the visual viewport is resizing.
// This will ensure that overlays adjust their positioning when the iOS virtual keyboard appears.
let isResizing = useRef(false);
useEffect(() => {
let timeout;
let onResize = () => {
isResizing.current = true;
clearTimeout(timeout);
timeout = setTimeout(() => {
isResizing.current = false;
}, 500);
updatePosition();
};
$adfbd034e9bc71c1$var$visualViewport == null ? void 0 : $adfbd034e9bc71c1$var$visualViewport.addEventListener('resize', onResize);
return () => {
$adfbd034e9bc71c1$var$visualViewport == null ? void 0 : $adfbd034e9bc71c1$var$visualViewport.removeEventListener('resize', onResize);
};
}, [updatePosition]);
let close = useCallback(() => {
if (!isResizing.current) {
onClose();
}
}, [onClose, isResizing]); // When scrolling a parent scrollable region of the trigger (other than the body),
// we hide the popover. Otherwise, its position would be incorrect.

@@ -430,3 +463,3 @@

isOpen,
onClose
onClose: onClose ? close : undefined
});

@@ -912,3 +945,3 @@ return {

*/
function useModal() {
function useModal(options) {
// Add aria-hidden to all parent providers on mount, and restore on unmount.

@@ -922,3 +955,3 @@ let context = useContext($c5f9596976ab8bd94c5879001549a3e$var$Context);

useEffect(() => {
if (!context || !context.parent) {
if ((options == null ? void 0 : options.isDisabled) || !context || !context.parent) {
return;

@@ -935,6 +968,6 @@ } // The immediate context is from the provider containing this modal, so we only

};
}, [context, context.parent]);
}, [context, context.parent, options == null ? void 0 : options.isDisabled]);
return {
modalProps: {
'data-ismodal': true
'data-ismodal': !(options == null ? void 0 : options.isDisabled)
}

@@ -1118,2 +1151,108 @@ };

exports.DismissButton = DismissButton;
// subtracted from when showing it again. When it reaches zero, aria-hidden is removed.
let $a683bb0d63d5b6f7885c12dcc6f96807$var$refCountMap = new WeakMap();
/**
* Hides all elements in the DOM outside the given targets from screen readers using aria-hidden,
* and returns a function to revert these changes. In addition, changes to the DOM are watched
* and new elements outside the targets are automatically hidden.
* @param targets - The elements that should remain visible.
* @param root - Nothing will be hidden above this element.
* @returns - A function to restore all hidden elements.
*/
function ariaHideOutside(targets, root) {
if (root === void 0) {
root = document.body;
}
let visibleNodes = new Set(targets);
let hiddenNodes = new Set();
let walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, {
acceptNode(node) {
// If this node is a live announcer, add it to the set of nodes to keep visible.
if (node instanceof HTMLElement && node.dataset.liveAnnouncer === 'true') {
visibleNodes.add(node);
} // Skip this node and its children if it is one of the target nodes, or a live announcer.
// Also skip children of already hidden nodes, as aria-hidden is recursive.
if (visibleNodes.has(node) || hiddenNodes.has(node.parentElement)) {
return NodeFilter.FILTER_REJECT;
} // Skip this node but continue to children if one of the targets is inside the node.
if (targets.some(target => node.contains(target))) {
return NodeFilter.FILTER_SKIP;
}
return NodeFilter.FILTER_ACCEPT;
}
});
let hide = node => {
var _refCountMap$get;
let refCount = (_refCountMap$get = $a683bb0d63d5b6f7885c12dcc6f96807$var$refCountMap.get(node)) != null ? _refCountMap$get : 0; // If already aria-hidden, and the ref count is zero, then this element
// was already hidden and there's nothing for us to do.
if (node.getAttribute('aria-hidden') === 'true' && refCount === 0) {
return;
}
if (refCount === 0) {
node.setAttribute('aria-hidden', 'true');
}
hiddenNodes.add(node);
$a683bb0d63d5b6f7885c12dcc6f96807$var$refCountMap.set(node, refCount + 1);
};
let node = walker.nextNode();
while (node != null) {
hide(node);
node = walker.nextNode();
}
let observer = new MutationObserver(changes => {
for (let change of changes) {
if (change.type !== 'childList' || change.addedNodes.length === 0) {
continue;
} // If the parent element of the added nodes is not within one of the targets,
// and not already inside a hidden node, hide all of the new children.
if (![...visibleNodes, ...hiddenNodes].some(node => node.contains(change.target))) {
for (let node of change.addedNodes) {
if (node instanceof HTMLElement && node.dataset.liveAnnouncer === 'true') {
visibleNodes.add(node);
} else if (node instanceof Element) {
hide(node);
}
}
}
}
});
observer.observe(root, {
childList: true,
subtree: true
});
return () => {
observer.disconnect();
for (let node of hiddenNodes) {
let count = $a683bb0d63d5b6f7885c12dcc6f96807$var$refCountMap.get(node);
if (count === 1) {
node.removeAttribute('aria-hidden');
$a683bb0d63d5b6f7885c12dcc6f96807$var$refCountMap.delete(node);
} else {
$a683bb0d63d5b6f7885c12dcc6f96807$var$refCountMap.set(node, count - 1);
}
}
};
}
exports.ariaHideOutside = ariaHideOutside;
//# sourceMappingURL=main.js.map

@@ -7,3 +7,3 @@ import { VisuallyHidden } from "@react-aria/visually-hidden";

import { useLocale, useMessageFormatter } from "@react-aria/i18n";
import _react, { useCallback, useEffect, useState, useLayoutEffect, useContext, useMemo } from "react";
import _react, { useCallback, useEffect, useRef, useState, useLayoutEffect, useContext, useMemo } from "react";
import _domHelpersOwnerDocument from "dom-helpers/ownerDocument";

@@ -36,4 +36,6 @@ import _domHelpersQueryScrollTop from "dom-helpers/query/scrollTop";

};
const $d45e305fb90d49e7c81f49bb4afe323b$var$PARSED_PLACEMENT_CACHE = {};
const $d45e305fb90d49e7c81f49bb4afe323b$var$PARSED_PLACEMENT_CACHE = {}; // @ts-ignore
let $d45e305fb90d49e7c81f49bb4afe323b$var$visualViewport = typeof window !== 'undefined' && window.visualViewport;
function $d45e305fb90d49e7c81f49bb4afe323b$var$getContainerDimensions(containerNode) {

@@ -47,4 +49,6 @@ let width = 0,

if (containerNode.tagName === 'BODY') {
width = document.documentElement.clientWidth;
height = document.documentElement.clientHeight;
var _visualViewport$width, _visualViewport$heigh;
width = (_visualViewport$width = $d45e305fb90d49e7c81f49bb4afe323b$var$visualViewport == null ? void 0 : $d45e305fb90d49e7c81f49bb4afe323b$var$visualViewport.width) != null ? _visualViewport$width : document.documentElement.clientWidth;
height = (_visualViewport$heigh = $d45e305fb90d49e7c81f49bb4afe323b$var$visualViewport == null ? void 0 : $d45e305fb90d49e7c81f49bb4afe323b$var$visualViewport.height) != null ? _visualViewport$heigh : document.documentElement.clientHeight;
scroll.top = _domHelpersQueryScrollTop(_domHelpersOwnerDocument(containerNode).documentElement) || _domHelpersQueryScrollTop(containerNode);

@@ -330,2 +334,4 @@ scroll.left = _domHelpersQueryScrollLeft(_domHelpersOwnerDocument(containerNode).documentElement) || _domHelpersQueryScrollLeft(containerNode);

// @ts-ignore
let $ae841ee9d3f76b31663cf0594adb0fc$var$visualViewport = typeof window !== 'undefined' && window.visualViewport;
/**

@@ -335,2 +341,3 @@ * Handles positioning overlays like popovers and menus relative to a trigger

*/
export function useOverlayPosition(props) {

@@ -382,3 +389,28 @@ let {

$ae841ee9d3f76b31663cf0594adb0fc$var$useResize(updatePosition); // When scrolling a parent scrollable region of the trigger (other than the body),
$ae841ee9d3f76b31663cf0594adb0fc$var$useResize(updatePosition); // Reposition the overlay and do not close on scroll while the visual viewport is resizing.
// This will ensure that overlays adjust their positioning when the iOS virtual keyboard appears.
let isResizing = useRef(false);
useEffect(() => {
let timeout;
let onResize = () => {
isResizing.current = true;
clearTimeout(timeout);
timeout = setTimeout(() => {
isResizing.current = false;
}, 500);
updatePosition();
};
$ae841ee9d3f76b31663cf0594adb0fc$var$visualViewport == null ? void 0 : $ae841ee9d3f76b31663cf0594adb0fc$var$visualViewport.addEventListener('resize', onResize);
return () => {
$ae841ee9d3f76b31663cf0594adb0fc$var$visualViewport == null ? void 0 : $ae841ee9d3f76b31663cf0594adb0fc$var$visualViewport.removeEventListener('resize', onResize);
};
}, [updatePosition]);
let close = useCallback(() => {
if (!isResizing.current) {
onClose();
}
}, [onClose, isResizing]); // When scrolling a parent scrollable region of the trigger (other than the body),
// we hide the popover. Otherwise, its position would be incorrect.

@@ -389,3 +421,3 @@

isOpen,
onClose
onClose: onClose ? close : undefined
});

@@ -852,3 +884,3 @@ return {

*/
export function useModal() {
export function useModal(options) {
// Add aria-hidden to all parent providers on mount, and restore on unmount.

@@ -862,3 +894,3 @@ let context = useContext($b876e5ac9c98db373bf726bce3d604e$var$Context);

useEffect(() => {
if (!context || !context.parent) {
if ((options == null ? void 0 : options.isDisabled) || !context || !context.parent) {
return;

@@ -875,6 +907,6 @@ } // The immediate context is from the provider containing this modal, so we only

};
}, [context, context.parent]);
}, [context, context.parent, options == null ? void 0 : options.isDisabled]);
return {
modalProps: {
'data-ismodal': true
'data-ismodal': !(options == null ? void 0 : options.isDisabled)
}

@@ -1054,2 +1086,106 @@ };

}
// subtracted from when showing it again. When it reaches zero, aria-hidden is removed.
let $d006cf2ec48f5151923b9435b3d$var$refCountMap = new WeakMap();
/**
* Hides all elements in the DOM outside the given targets from screen readers using aria-hidden,
* and returns a function to revert these changes. In addition, changes to the DOM are watched
* and new elements outside the targets are automatically hidden.
* @param targets - The elements that should remain visible.
* @param root - Nothing will be hidden above this element.
* @returns - A function to restore all hidden elements.
*/
export function ariaHideOutside(targets, root) {
if (root === void 0) {
root = document.body;
}
let visibleNodes = new Set(targets);
let hiddenNodes = new Set();
let walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, {
acceptNode(node) {
// If this node is a live announcer, add it to the set of nodes to keep visible.
if (node instanceof HTMLElement && node.dataset.liveAnnouncer === 'true') {
visibleNodes.add(node);
} // Skip this node and its children if it is one of the target nodes, or a live announcer.
// Also skip children of already hidden nodes, as aria-hidden is recursive.
if (visibleNodes.has(node) || hiddenNodes.has(node.parentElement)) {
return NodeFilter.FILTER_REJECT;
} // Skip this node but continue to children if one of the targets is inside the node.
if (targets.some(target => node.contains(target))) {
return NodeFilter.FILTER_SKIP;
}
return NodeFilter.FILTER_ACCEPT;
}
});
let hide = node => {
var _refCountMap$get;
let refCount = (_refCountMap$get = $d006cf2ec48f5151923b9435b3d$var$refCountMap.get(node)) != null ? _refCountMap$get : 0; // If already aria-hidden, and the ref count is zero, then this element
// was already hidden and there's nothing for us to do.
if (node.getAttribute('aria-hidden') === 'true' && refCount === 0) {
return;
}
if (refCount === 0) {
node.setAttribute('aria-hidden', 'true');
}
hiddenNodes.add(node);
$d006cf2ec48f5151923b9435b3d$var$refCountMap.set(node, refCount + 1);
};
let node = walker.nextNode();
while (node != null) {
hide(node);
node = walker.nextNode();
}
let observer = new MutationObserver(changes => {
for (let change of changes) {
if (change.type !== 'childList' || change.addedNodes.length === 0) {
continue;
} // If the parent element of the added nodes is not within one of the targets,
// and not already inside a hidden node, hide all of the new children.
if (![...visibleNodes, ...hiddenNodes].some(node => node.contains(change.target))) {
for (let node of change.addedNodes) {
if (node instanceof HTMLElement && node.dataset.liveAnnouncer === 'true') {
visibleNodes.add(node);
} else if (node instanceof Element) {
hide(node);
}
}
}
}
});
observer.observe(root, {
childList: true,
subtree: true
});
return () => {
observer.disconnect();
for (let node of hiddenNodes) {
let count = $d006cf2ec48f5151923b9435b3d$var$refCountMap.get(node);
if (count === 1) {
node.removeAttribute('aria-hidden');
$d006cf2ec48f5151923b9435b3d$var$refCountMap.delete(node);
} else {
$d006cf2ec48f5151923b9435b3d$var$refCountMap.set(node, count - 1);
}
}
};
}
//# sourceMappingURL=module.js.map

@@ -151,2 +151,5 @@ import React, { HTMLAttributes, RefObject, AriaAttributes, ReactNode } from "react";

}
interface ModalOptions {
isDisabled?: boolean;
}
interface ModalAria {

@@ -162,3 +165,3 @@ /** Props for the modal content element. */

*/
export function useModal(): ModalAria;
export function useModal(options?: ModalOptions): ModalAria;
interface DismissButtonProps {

@@ -174,3 +177,12 @@ /** Called when the dismiss button is activated. */

export function DismissButton(props: DismissButtonProps): JSX.Element;
/**
* Hides all elements in the DOM outside the given targets from screen readers using aria-hidden,
* and returns a function to revert these changes. In addition, changes to the DOM are watched
* and new elements outside the targets are automatically hidden.
* @param targets - The elements that should remain visible.
* @param root - Nothing will be hidden above this element.
* @returns - A function to restore all hidden elements.
*/
export function ariaHideOutside(targets: HTMLElement[], root?: HTMLElement): () => void;
//# sourceMappingURL=types.d.ts.map

18

package.json
{
"name": "@react-aria/overlays",
"version": "3.0.0-nightly.767+df4650ba",
"version": "3.0.0-nightly.770+28ceccbf",
"description": "Spectrum UI components in React",

@@ -21,9 +21,9 @@ "license": "Apache-2.0",

"@babel/runtime": "^7.6.2",
"@react-aria/i18n": "3.0.0-nightly.767+df4650ba",
"@react-aria/interactions": "3.0.0-nightly.767+df4650ba",
"@react-aria/utils": "3.0.0-nightly.767+df4650ba",
"@react-aria/visually-hidden": "3.0.0-nightly.767+df4650ba",
"@react-stately/overlays": "3.1.2-nightly.2445+df4650ba",
"@react-types/button": "3.2.2-nightly.2445+df4650ba",
"@react-types/overlays": "3.3.1-nightly.2445+df4650ba",
"@react-aria/i18n": "3.0.0-nightly.770+28ceccbf",
"@react-aria/interactions": "3.0.0-nightly.770+28ceccbf",
"@react-aria/utils": "3.0.0-nightly.770+28ceccbf",
"@react-aria/visually-hidden": "3.0.0-nightly.770+28ceccbf",
"@react-stately/overlays": "3.1.2-nightly.2448+28ceccbf",
"@react-types/button": "3.2.2-nightly.2448+28ceccbf",
"@react-types/overlays": "3.3.1-nightly.2448+28ceccbf",
"dom-helpers": "^3.3.1"

@@ -38,3 +38,3 @@ },

},
"gitHead": "df4650ba218034780d86a0ce0459bbe7f88cc1ce"
"gitHead": "28ceccbf05637e9fb256794a16c0152e52be179e"
}

@@ -98,2 +98,5 @@ /*

// @ts-ignore
let visualViewport = typeof window !== 'undefined' && window.visualViewport;
function getContainerDimensions(containerNode: Element): Dimensions {

@@ -104,4 +107,4 @@ let width = 0, height = 0, top = 0, left = 0;

if (containerNode.tagName === 'BODY') {
width = document.documentElement.clientWidth;
height = document.documentElement.clientHeight;
width = visualViewport?.width ?? document.documentElement.clientWidth;
height = visualViewport?.height ?? document.documentElement.clientHeight;

@@ -108,0 +111,0 @@ scroll.top =

@@ -19,1 +19,2 @@ /*

export * from './DismissButton';
export * from './ariaHideOutside';

@@ -14,3 +14,3 @@ /*

import {calculatePosition, PositionResult} from './calculatePosition';
import {HTMLAttributes, RefObject, useCallback, useEffect, useState} from 'react';
import {HTMLAttributes, RefObject, useCallback, useEffect, useRef, useState} from 'react';
import {Placement, PlacementAxis, PositionProps} from '@react-types/overlays';

@@ -59,2 +59,5 @@ import {useCloseOnScroll} from './useCloseOnScroll';

// @ts-ignore
let visualViewport = typeof window !== 'undefined' && window.visualViewport;
/**

@@ -129,2 +132,31 @@ * Handles positioning overlays like popovers and menus relative to a trigger

// Reposition the overlay and do not close on scroll while the visual viewport is resizing.
// This will ensure that overlays adjust their positioning when the iOS virtual keyboard appears.
let isResizing = useRef(false);
useEffect(() => {
let timeout: NodeJS.Timeout;
let onResize = () => {
isResizing.current = true;
clearTimeout(timeout);
timeout = setTimeout(() => {
isResizing.current = false;
}, 500);
updatePosition();
};
visualViewport?.addEventListener('resize', onResize);
return () => {
visualViewport?.removeEventListener('resize', onResize);
};
}, [updatePosition]);
let close = useCallback(() => {
if (!isResizing.current) {
onClose();
}
}, [onClose, isResizing]);
// When scrolling a parent scrollable region of the trigger (other than the body),

@@ -135,3 +167,3 @@ // we hide the popover. Otherwise, its position would be incorrect.

isOpen,
onClose
onClose: onClose ? close : undefined
});

@@ -138,0 +170,0 @@

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

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc