aria-hidden
Advanced tools
Comparing version 1.1.3 to 1.2.0
export declare type Undo = () => void; | ||
export declare const hideOthers: (originalTarget: Element | Element[], parentNode?: HTMLElement, markerName?: string) => Undo; | ||
/** | ||
* Marks everything except given node(or nodes) as aria-hidden | ||
* @param {Element | Element[]} originalTarget - elements to keep on the page | ||
* @param [parentNode] - top element, defaults to document.body | ||
* @param {String} [markerName] - a special attribute to mark every node | ||
* @return {Undo} undo command | ||
*/ | ||
export declare const hideOthers: (originalTarget: Element | Element[], parentNode: HTMLElement | undefined, markerName?: string) => Undo; | ||
/** | ||
* Marks everything except given node(or nodes) as inert | ||
* @param {Element | Element[]} originalTarget - elements to keep on the page | ||
* @param [parentNode] - top element, defaults to document.body | ||
* @param {String} [markerName] - a special attribute to mark every node | ||
* @return {Undo} undo command | ||
*/ | ||
export declare const inertOthers: (originalTarget: Element | Element[], parentNode: HTMLElement | undefined, markerName?: string) => Undo; | ||
/** | ||
* @returns if current browser supports inert | ||
*/ | ||
export declare const supportsInert: () => boolean; | ||
/** | ||
* Automatic function to "suppress" DOM elements - _hide_ or _inert_ in the best possible way | ||
* @param {Element | Element[]} originalTarget - elements to keep on the page | ||
* @param [parentNode] - top element, defaults to document.body | ||
* @param {String} [markerName] - a special attribute to mark every node | ||
* @return {Undo} undo command | ||
*/ | ||
export declare const suppressOthers: (originalTarget: Element | Element[], parentNode: HTMLElement | undefined, markerName?: string) => Undo; |
@@ -12,5 +12,11 @@ var getDefaultParent = function (originalTarget) { | ||
var lockCount = 0; | ||
export var hideOthers = function (originalTarget, parentNode, markerName) { | ||
if (parentNode === void 0) { parentNode = getDefaultParent(originalTarget); } | ||
if (markerName === void 0) { markerName = "data-aria-hidden"; } | ||
/** | ||
* Marks everything except given node(or nodes) as aria-hidden | ||
* @param {Element | Element[]} originalTarget - elements to keep on the page | ||
* @param [parentNode] - top element, defaults to document.body | ||
* @param {String} [markerName] - a special attribute to mark every node | ||
* @param {String} [controlAttribute] - html Attribute to control | ||
* @return {Undo} undo command | ||
*/ | ||
var applyAttributeToOthers = function (originalTarget, parentNode, markerName, controlAttribute) { | ||
var targets = Array.isArray(originalTarget) ? originalTarget : [originalTarget]; | ||
@@ -23,3 +29,4 @@ if (!markerMap[markerName]) { | ||
var elementsToKeep = new Set(); | ||
var keep = (function (el) { | ||
var elementsToStop = new Set(targets); | ||
var keep = function (el) { | ||
if (!el || elementsToKeep.has(el)) { | ||
@@ -30,6 +37,6 @@ return; | ||
keep(el.parentNode); | ||
}); | ||
}; | ||
targets.forEach(keep); | ||
var deep = function (parent) { | ||
if (!parent || targets.indexOf(parent) >= 0) { | ||
if (!parent || elementsToStop.has(parent)) { | ||
return; | ||
@@ -42,3 +49,3 @@ } | ||
else { | ||
var attr = node.getAttribute('aria-hidden'); | ||
var attr = node.getAttribute(controlAttribute); | ||
var alreadyHidden = attr !== null && attr !== 'false'; | ||
@@ -57,3 +64,3 @@ var counterValue = (counterMap.get(node) || 0) + 1; | ||
if (!alreadyHidden) { | ||
node.setAttribute('aria-hidden', 'true'); | ||
node.setAttribute(controlAttribute, 'true'); | ||
} | ||
@@ -74,3 +81,3 @@ } | ||
if (!uncontrolledNodes.has(node)) { | ||
node.removeAttribute('aria-hidden'); | ||
node.removeAttribute(controlAttribute); | ||
} | ||
@@ -85,2 +92,3 @@ uncontrolledNodes.delete(node); | ||
if (!lockCount) { | ||
// clear | ||
counterMap = new WeakMap(); | ||
@@ -93,1 +101,51 @@ counterMap = new WeakMap(); | ||
}; | ||
/** | ||
* Marks everything except given node(or nodes) as aria-hidden | ||
* @param {Element | Element[]} originalTarget - elements to keep on the page | ||
* @param [parentNode] - top element, defaults to document.body | ||
* @param {String} [markerName] - a special attribute to mark every node | ||
* @return {Undo} undo command | ||
*/ | ||
export var hideOthers = function (originalTarget, parentNode, markerName) { | ||
if (markerName === void 0) { markerName = 'data-aria-hidden'; } | ||
var targets = Array.from(Array.isArray(originalTarget) ? originalTarget : [originalTarget]); | ||
var activeParentNode = parentNode || getDefaultParent(originalTarget); | ||
if (!activeParentNode) { | ||
return function () { return null; }; | ||
} | ||
// we should not hide ariaLive elements - https://github.com/theKashey/aria-hidden/issues/10 | ||
targets.push.apply(targets, Array.from(activeParentNode.querySelectorAll('[aria-live]'))); | ||
return applyAttributeToOthers(targets, activeParentNode, markerName, 'aria-hidden'); | ||
}; | ||
/** | ||
* Marks everything except given node(or nodes) as inert | ||
* @param {Element | Element[]} originalTarget - elements to keep on the page | ||
* @param [parentNode] - top element, defaults to document.body | ||
* @param {String} [markerName] - a special attribute to mark every node | ||
* @return {Undo} undo command | ||
*/ | ||
export var inertOthers = function (originalTarget, parentNode, markerName) { | ||
if (markerName === void 0) { markerName = 'data-inert-ed'; } | ||
var activeParentNode = parentNode || getDefaultParent(originalTarget); | ||
if (!activeParentNode) { | ||
return function () { return null; }; | ||
} | ||
return applyAttributeToOthers(originalTarget, activeParentNode, markerName, 'inert'); | ||
}; | ||
/** | ||
* @returns if current browser supports inert | ||
*/ | ||
export var supportsInert = function () { | ||
return typeof HTMLElement !== 'undefined' && HTMLElement.prototype.hasOwnProperty('inert'); | ||
}; | ||
/** | ||
* Automatic function to "suppress" DOM elements - _hide_ or _inert_ in the best possible way | ||
* @param {Element | Element[]} originalTarget - elements to keep on the page | ||
* @param [parentNode] - top element, defaults to document.body | ||
* @param {String} [markerName] - a special attribute to mark every node | ||
* @return {Undo} undo command | ||
*/ | ||
export var suppressOthers = function (originalTarget, parentNode, markerName) { | ||
if (markerName === void 0) { markerName = 'data-suppressed'; } | ||
return (supportsInert() ? inertOthers : hideOthers)(originalTarget, parentNode, markerName); | ||
}; |
export declare type Undo = () => void; | ||
export declare const hideOthers: (originalTarget: Element | Element[], parentNode?: HTMLElement, markerName?: string) => Undo; | ||
/** | ||
* Marks everything except given node(or nodes) as aria-hidden | ||
* @param {Element | Element[]} originalTarget - elements to keep on the page | ||
* @param [parentNode] - top element, defaults to document.body | ||
* @param {String} [markerName] - a special attribute to mark every node | ||
* @return {Undo} undo command | ||
*/ | ||
export declare const hideOthers: (originalTarget: Element | Element[], parentNode: HTMLElement | undefined, markerName?: string) => Undo; | ||
/** | ||
* Marks everything except given node(or nodes) as inert | ||
* @param {Element | Element[]} originalTarget - elements to keep on the page | ||
* @param [parentNode] - top element, defaults to document.body | ||
* @param {String} [markerName] - a special attribute to mark every node | ||
* @return {Undo} undo command | ||
*/ | ||
export declare const inertOthers: (originalTarget: Element | Element[], parentNode: HTMLElement | undefined, markerName?: string) => Undo; | ||
/** | ||
* @returns if current browser supports inert | ||
*/ | ||
export declare const supportsInert: () => boolean; | ||
/** | ||
* Automatic function to "suppress" DOM elements - _hide_ or _inert_ in the best possible way | ||
* @param {Element | Element[]} originalTarget - elements to keep on the page | ||
* @param [parentNode] - top element, defaults to document.body | ||
* @param {String} [markerName] - a special attribute to mark every node | ||
* @return {Undo} undo command | ||
*/ | ||
export declare const suppressOthers: (originalTarget: Element | Element[], parentNode: HTMLElement | undefined, markerName?: string) => Undo; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.suppressOthers = exports.supportsInert = exports.inertOthers = exports.hideOthers = void 0; | ||
var getDefaultParent = function (originalTarget) { | ||
@@ -14,5 +15,11 @@ if (typeof document === 'undefined') { | ||
var lockCount = 0; | ||
exports.hideOthers = function (originalTarget, parentNode, markerName) { | ||
if (parentNode === void 0) { parentNode = getDefaultParent(originalTarget); } | ||
if (markerName === void 0) { markerName = "data-aria-hidden"; } | ||
/** | ||
* Marks everything except given node(or nodes) as aria-hidden | ||
* @param {Element | Element[]} originalTarget - elements to keep on the page | ||
* @param [parentNode] - top element, defaults to document.body | ||
* @param {String} [markerName] - a special attribute to mark every node | ||
* @param {String} [controlAttribute] - html Attribute to control | ||
* @return {Undo} undo command | ||
*/ | ||
var applyAttributeToOthers = function (originalTarget, parentNode, markerName, controlAttribute) { | ||
var targets = Array.isArray(originalTarget) ? originalTarget : [originalTarget]; | ||
@@ -25,3 +32,4 @@ if (!markerMap[markerName]) { | ||
var elementsToKeep = new Set(); | ||
var keep = (function (el) { | ||
var elementsToStop = new Set(targets); | ||
var keep = function (el) { | ||
if (!el || elementsToKeep.has(el)) { | ||
@@ -32,6 +40,6 @@ return; | ||
keep(el.parentNode); | ||
}); | ||
}; | ||
targets.forEach(keep); | ||
var deep = function (parent) { | ||
if (!parent || targets.indexOf(parent) >= 0) { | ||
if (!parent || elementsToStop.has(parent)) { | ||
return; | ||
@@ -44,3 +52,3 @@ } | ||
else { | ||
var attr = node.getAttribute('aria-hidden'); | ||
var attr = node.getAttribute(controlAttribute); | ||
var alreadyHidden = attr !== null && attr !== 'false'; | ||
@@ -59,3 +67,3 @@ var counterValue = (counterMap.get(node) || 0) + 1; | ||
if (!alreadyHidden) { | ||
node.setAttribute('aria-hidden', 'true'); | ||
node.setAttribute(controlAttribute, 'true'); | ||
} | ||
@@ -76,3 +84,3 @@ } | ||
if (!uncontrolledNodes.has(node)) { | ||
node.removeAttribute('aria-hidden'); | ||
node.removeAttribute(controlAttribute); | ||
} | ||
@@ -87,2 +95,3 @@ uncontrolledNodes.delete(node); | ||
if (!lockCount) { | ||
// clear | ||
counterMap = new WeakMap(); | ||
@@ -95,1 +104,55 @@ counterMap = new WeakMap(); | ||
}; | ||
/** | ||
* Marks everything except given node(or nodes) as aria-hidden | ||
* @param {Element | Element[]} originalTarget - elements to keep on the page | ||
* @param [parentNode] - top element, defaults to document.body | ||
* @param {String} [markerName] - a special attribute to mark every node | ||
* @return {Undo} undo command | ||
*/ | ||
var hideOthers = function (originalTarget, parentNode, markerName) { | ||
if (markerName === void 0) { markerName = 'data-aria-hidden'; } | ||
var targets = Array.from(Array.isArray(originalTarget) ? originalTarget : [originalTarget]); | ||
var activeParentNode = parentNode || getDefaultParent(originalTarget); | ||
if (!activeParentNode) { | ||
return function () { return null; }; | ||
} | ||
// we should not hide ariaLive elements - https://github.com/theKashey/aria-hidden/issues/10 | ||
targets.push.apply(targets, Array.from(activeParentNode.querySelectorAll('[aria-live]'))); | ||
return applyAttributeToOthers(targets, activeParentNode, markerName, 'aria-hidden'); | ||
}; | ||
exports.hideOthers = hideOthers; | ||
/** | ||
* Marks everything except given node(or nodes) as inert | ||
* @param {Element | Element[]} originalTarget - elements to keep on the page | ||
* @param [parentNode] - top element, defaults to document.body | ||
* @param {String} [markerName] - a special attribute to mark every node | ||
* @return {Undo} undo command | ||
*/ | ||
var inertOthers = function (originalTarget, parentNode, markerName) { | ||
if (markerName === void 0) { markerName = 'data-inert-ed'; } | ||
var activeParentNode = parentNode || getDefaultParent(originalTarget); | ||
if (!activeParentNode) { | ||
return function () { return null; }; | ||
} | ||
return applyAttributeToOthers(originalTarget, activeParentNode, markerName, 'inert'); | ||
}; | ||
exports.inertOthers = inertOthers; | ||
/** | ||
* @returns if current browser supports inert | ||
*/ | ||
var supportsInert = function () { | ||
return typeof HTMLElement !== 'undefined' && HTMLElement.prototype.hasOwnProperty('inert'); | ||
}; | ||
exports.supportsInert = supportsInert; | ||
/** | ||
* Automatic function to "suppress" DOM elements - _hide_ or _inert_ in the best possible way | ||
* @param {Element | Element[]} originalTarget - elements to keep on the page | ||
* @param [parentNode] - top element, defaults to document.body | ||
* @param {String} [markerName] - a special attribute to mark every node | ||
* @return {Undo} undo command | ||
*/ | ||
var suppressOthers = function (originalTarget, parentNode, markerName) { | ||
if (markerName === void 0) { markerName = 'data-suppressed'; } | ||
return ((0, exports.supportsInert)() ? exports.inertOthers : exports.hideOthers)(originalTarget, parentNode, markerName); | ||
}; | ||
exports.suppressOthers = suppressOthers; |
{ | ||
"name": "aria-hidden", | ||
"version": "1.1.3", | ||
"version": "1.2.0", | ||
"description": "Cast aria-hidden to everything, except...", | ||
"main": "dist/es5/index.js", | ||
"sideEffects": false, | ||
"scripts": { | ||
"test": "ts-react-toolbox test", | ||
"bootstrap": "ts-react-toolbox init", | ||
"dev": "ts-react-toolbox dev", | ||
"test:ci": "ts-react-toolbox test --runInBand --coverage", | ||
"build": "ts-react-toolbox build", | ||
"test": "jest", | ||
"dev": "lib-builder dev", | ||
"test:ci": "jest --runInBand --coverage", | ||
"build": "lib-builder build && yarn size:report", | ||
"prepublish": "yarn build", | ||
"release": "ts-react-toolbox release", | ||
"lint": "ts-react-toolbox lint", | ||
"static": "ts-react-toolbox publish", | ||
"format": "ts-react-toolbox format", | ||
"analyze": "ts-react-toolbox analyze" | ||
"release": "yarn build && yarn test", | ||
"lint": "lib-builder lint", | ||
"format": "lib-builder format", | ||
"analyze": "ts-react-toolbox analyze", | ||
"size": "npx size-limit", | ||
"size:report": "npx size-limit --json > .size.json", | ||
"update": "lib-builder update", | ||
"prepublish-only": "yarn build && yarn changelog", | ||
"prepare": "husky install", | ||
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s", | ||
"changelog:rewrite": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0" | ||
}, | ||
"author": "Anton Korzunov <thekashey@gmail.com>", | ||
"license": "ISC", | ||
"license": "MIT", | ||
"devDependencies": { | ||
"ts-react-toolbox": "^0.1.22" | ||
"@theuiteam/lib-builder": "^0.2.1", | ||
"@size-limit/preset-small-lib": "^2.1.6" | ||
}, | ||
"engines": { | ||
"node": ">=8.5.0" | ||
"node": ">=10" | ||
}, | ||
@@ -45,4 +52,30 @@ "jsnext:main": "dist/es2015/index.js", | ||
"dependencies": { | ||
"tslib": "^1.0.0" | ||
"tslib": "^2.0.0" | ||
}, | ||
"module:es2019": "dist/es2019/index.js", | ||
"peerDependencies": { | ||
"react": "^16.9.0 || ^17.0.0 || ^18.0.0", | ||
"@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0" | ||
}, | ||
"peerDependenciesMeta": { | ||
"@types/react": { | ||
"optional": true | ||
} | ||
}, | ||
"lint-staged": { | ||
"*.{ts,tsx}": [ | ||
"prettier --write", | ||
"eslint --fix" | ||
], | ||
"*.{js,css,json,md}": [ | ||
"prettier --write" | ||
] | ||
}, | ||
"prettier": { | ||
"printWidth": 120, | ||
"trailingComma": "es5", | ||
"tabWidth": 2, | ||
"semi": true, | ||
"singleQuote": true | ||
} | ||
} |
@@ -1,33 +0,68 @@ | ||
aria-hidden | ||
==== | ||
# aria-hidden | ||
[![NPM](https://nodei.co/npm/aria-hidden.png?downloads=true&stars=true)](https://nodei.co/npm/aria-hidden/) | ||
Hides from ARIA everything, except provided node. | ||
Hides from ARIA everything, except provided node(s). | ||
Helps to isolate modal dialogs and focused task - the content will be not accessible using | ||
accesible tools. | ||
accessible tools. | ||
Now with [HTML inert](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/inert) support | ||
# API | ||
Just call `hideOthers` with DOM-node you want to keep, and it will hide everything else. | ||
targetNode could be placed anywhere - its siblings would be hidden, but its parents - not. | ||
Just call `hideOthers` with DOM-node you want to keep, and it will _hide_ everything else. | ||
`targetNode` could be placed anywhere - its siblings would be hidden, but it and its parents - not. | ||
> "hidden" in terms or `aria-hidden` | ||
```js | ||
import {hideOthers} from 'aria-hidden'; | ||
import { hideOthers } from 'aria-hidden'; | ||
const undo = hideOthers(DOMnode); | ||
const undo = hideOthers(exceptThisDOMnode); | ||
// everything else is "aria-hidden" | ||
// undo changes | ||
undo(); | ||
// all changes undone | ||
``` | ||
you also may limit the effect by providing top level node as a second paramiter | ||
you also may limit the effect spread by providing top level node as a second parameter | ||
```js | ||
hideOthers(targetNode, parentNode); | ||
hideOthers(anotherNode, document.getElementById('app')); | ||
// parentNode defaults to document.body | ||
// keep only `anotherNode` node visible in #app | ||
// the rest of document will be untouched | ||
hideOthers(anotherNode, document.getElementById('app')); | ||
``` | ||
> `parentNode` defaults to document.body | ||
# Inert | ||
While `aria-hidden` played important role in the past and will play in the future - the main | ||
use case always was around isolating content and making elements "transparent" not only for aria, but for | ||
user interaction as well. | ||
This is why you might consider using `inertOthers` | ||
```tsx | ||
import { hideOthers, inertOthers, supportsInert } from 'aria-hidden'; | ||
// focus on element mean "hide others". Ideally disable interactions | ||
const focusOnElement = (node) => (supportsInert() ? inertOthers(node) : hideOthers(node)); | ||
``` | ||
the same function as above is already contructed and exported as | ||
```tsx | ||
import { suppressOthers } from 'aria-hidden'; | ||
suppressOthers([keepThisNode, andThis]); | ||
``` | ||
# Inspiration | ||
Based on [smooth-ui](https://github.com/smooth-code/smooth-ui) modal dialogs. | ||
# See also | ||
- [inert](https://github.com/WICG/inert) - The HTML attribute/property to mark parts of the DOM tree as "inert". | ||
@@ -37,6 +72,8 @@ - [react-focus-lock](https://github.com/theKashey/react-focus-lock) to lock Focus inside modal. | ||
# Size | ||
# Size | ||
Code is 30 lines long | ||
# Licence | ||
MIT | ||
# Licence | ||
MIT |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
27829
9
516
79
3
2
1
+ Added@types/prop-types@15.7.12(transitive)
+ Added@types/react@18.3.2(transitive)
+ Addedcsstype@3.1.3(transitive)
+ Addedjs-tokens@4.0.0(transitive)
+ Addedloose-envify@1.4.0(transitive)
+ Addedreact@18.3.1(transitive)
+ Addedtslib@2.6.2(transitive)
- Removedtslib@1.14.1(transitive)
Updatedtslib@^2.0.0