-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: support hiding via inert attribute
- Loading branch information
Showing
12 changed files
with
287 additions
and
145 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
#!/bin/sh | ||
. "$(dirname "$0")/_/husky.sh" | ||
|
||
lint-staged | ||
yarn lint-staged |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,6 @@ | |
{ | ||
"name": "dist/es2015/index.js", | ||
"passed": true, | ||
"size": 454 | ||
"size": 599 | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,78 @@ | ||
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". | ||
- [react-focus-lock](https://github.com/theKashey/react-focus-lock) to lock Focus inside modal. | ||
- [react-scroll-lock](https://github.com/theKashey/react-scroll-lock) to disable page scroll while modal is opened. | ||
|
||
# Size | ||
# Size | ||
|
||
Code is 30 lines long | ||
|
||
# Licence | ||
MIT | ||
# Licence | ||
|
||
MIT |
2 changes: 0 additions & 2 deletions
2
__tests__/__snapshots__/index.tsx.snap → __tests__/__snapshots__/aria.spec.tsx.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { render } from '@testing-library/react'; | ||
import * as React from 'react'; | ||
|
||
import { inertOthers, supportsInert } from '../src'; | ||
import { getNearestAttribute } from './utils'; | ||
|
||
describe('inert', () => { | ||
it('supports in jsdom', () => { | ||
// not yet | ||
expect(supportsInert()).toBeFalsy(); | ||
}); | ||
|
||
it('handles inert', () => { | ||
const wrapper = render( | ||
<div> | ||
<div> | ||
<div id="to-be-hidden">hidden</div> | ||
</div> | ||
<div id="not-to-be-hidden">not-hidden</div> | ||
</div> | ||
); | ||
const root = wrapper.baseElement.firstElementChild!; | ||
|
||
const unhide = inertOthers(root.firstElementChild!.lastElementChild!, root as any); | ||
|
||
expect(getNearestAttribute(root.querySelector('#to-be-hidden')!, 'inert', { current: root })).toBe('true'); | ||
expect(getNearestAttribute(root.querySelector('#not-to-be-hidden')!, 'inert', { current: root })).toBe(null); | ||
|
||
expect(wrapper.baseElement.innerHTML).toMatchInlineSnapshot( | ||
`"<div><div><div data-inert-ed=\\"true\\" inert=\\"true\\"><div id=\\"to-be-hidden\\">hidden</div></div><div id=\\"not-to-be-hidden\\">not-hidden</div></div></div>"` | ||
); | ||
|
||
unhide(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/** | ||
* @jest-environment node | ||
*/ | ||
|
||
import { supportsInert } from '../src'; | ||
|
||
describe('smoke ssr', () => { | ||
it('do not throw', () => { | ||
expect(supportsInert()).toBeFalsy(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { RefObject } from 'react'; | ||
|
||
export const getNearestAttribute = (node: Element, name: string, parent: RefObject<Element> | Element): any => { | ||
const attr = node.getAttribute(name); | ||
|
||
if (attr) { | ||
return attr; | ||
} | ||
|
||
// @ts-ignore | ||
if (node === parent || node === parent.current || !node.parentNode) { | ||
return null; | ||
} | ||
|
||
return getNearestAttribute(node.parentNode as any, name, parent); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
module.exports = { | ||
preset: 'ts-jest', | ||
testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'], | ||
testPathIgnorePatterns: ['<rootDir>/dist/', '<rootDir>/node_modules/'], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.