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

tabbable

Package Overview
Dependencies
Maintainers
1
Versions
47
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tabbable - npm Package Compare versions

Comparing version 3.0.0 to 3.1.0

4

CHANGELOG.md
# Changelog
## 3.1.0
- Add `focusTrap.isFocusable` and `focusTrap.isTabbable` functions.
## 3.0.0

@@ -4,0 +8,0 @@

65

index.js

@@ -12,6 +12,7 @@ var candidateSelectors = [

];
var candidateSelector = candidateSelectors.join(',');
var matches = Element.prototype.matches || Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
module.exports = function tabbable(el, options) {
function tabbable(el, options) {
options = options || {};

@@ -24,9 +25,6 @@

var untouchabilityChecker = new UntouchabilityChecker(elementDocument);
var candidates = el.querySelectorAll(candidateSelectors.join(','));
var candidates = el.querySelectorAll(candidateSelector);
if (options.includeContainer) {
var containerIsCandidate = candidateSelectors.some(function(selector) {
return matches.call(el, selector);
});
if (containerIsCandidate) {
if (matches.call(el, candidateSelector)) {
candidates = Array.prototype.slice.apply(candidates);

@@ -40,14 +38,6 @@ candidates.unshift(el);

candidate = candidates[i];
candidateTabindex = getTabindex(candidate);
if (
candidateTabindex < 0
|| candidate.disabled
|| isHiddenInput(candidate)
|| isNonTabbableRadio(candidate)
|| untouchabilityChecker.isUntouchable(candidate)
) {
continue;
}
if (!isNodeMatchingSelectorTabbable(candidate, untouchabilityChecker)) continue;
candidateTabindex = getTabindex(candidate);
if (candidateTabindex === 0) {

@@ -72,2 +62,41 @@ regularTabbables.push(candidate);

tabbable.isTabbable = isTabbable;
tabbable.isFocusable = isFocusable;
function isNodeMatchingSelectorTabbable(node, untouchabilityChecker) {
if (
!isNodeMatchingSelectorFocusable(node, untouchabilityChecker)
|| isNonTabbableRadio(node)
|| getTabindex(node) < 0
) {
return false;
}
return true;
}
function isTabbable(node, untouchabilityChecker) {
if (!node) throw new Error('No node provided');
if (matches.call(node, candidateSelector) === false) return false;
return isNodeMatchingSelectorTabbable(node, untouchabilityChecker);
}
function isNodeMatchingSelectorFocusable(node, untouchabilityChecker) {
untouchabilityChecker = untouchabilityChecker || new UntouchabilityChecker(node.ownerDocument || node);
if (
node.disabled
|| isHiddenInput(node)
|| untouchabilityChecker.isUntouchable(node)
) {
return false;
}
return true;
}
var focusableCandidateSelector = candidateSelectors.concat('iframe').join(',');
function isFocusable(node, untouchabilityChecker) {
if (!node) throw new Error('No node provided');
if (matches.call(node, focusableCandidateSelector) === false) return false;
return isNodeMatchingSelectorFocusable(node, untouchabilityChecker);
}
function getTabindex(node) {

@@ -94,3 +123,3 @@ var tabindexAttr = parseInt(node.getAttribute('tabindex'), 10);

function isContentEditable(node) {
return node.contentEditable === "true";
return node.contentEditable === 'true';
}

@@ -173,1 +202,3 @@

}
module.exports = tabbable;
{
"name": "tabbable",
"version": "3.0.0",
"version": "3.1.0",
"description": "Returns an array of all tabbable DOM nodes within a containing node.",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -5,8 +5,6 @@ # tabbable

Returns an array of all\* tabbable DOM nodes within a containing node.
Returns an array of all\* tabbable DOM nodes within a containing node. (\* "all" has some necessary caveats, which you'll learn about by reading below.)
(\* "all" has some necessary caveats, which you'll learn about by reading below.)
The following are considered tabbable:
The array of tabbable nodes should include the following:
- `<button>`s

@@ -21,3 +19,3 @@ - `<input>`s

Any of the above will *not* be added to the array, though, if any of the following are also true about it:
Any of the above will *not* be considered tabbable, though, if any of the following are also true about it:

@@ -29,7 +27,7 @@ - negative `tabindex`

**If you think a node should be included in your array of tabbables *but it's not*, all you need to do is add `tabindex="0"` to deliberately include it.** (Or if it is in your array but you don't want it, you can add `tabindex="-1" to deliberately exclude it.) This will also result in more consistent cross-browser behavior. For information about why your special node might *not* be included, see ["More details"](#more-details), below.
**If you think a node should be included in your array of tabbables *but it's not*, all you need to do is add `tabindex="0"` to deliberately include it.** (Or if it is in your array but you don't want it, you can add `tabindex="-1"` to deliberately exclude it.) This will also result in more consistent cross-browser behavior. For information about why your special node might *not* be included, see ["More details"](#more-details), below.
## Goals
- Accurate
- Accurate (or, as accurate as possible & reasonable)
- No dependencies

@@ -57,2 +55,4 @@ - Small

### tabbable
```

@@ -68,9 +68,9 @@ tabbable(rootNode, [options])

### rootNode
#### rootNode
Type: `Node`. **Required.**
### options
#### options
#### includeContainer
##### includeContainer

@@ -81,6 +81,24 @@ Type: `boolean`. Default: `false`.

### tabbable.isTabbable
```
tabbable.isTabbable(node)
```
Returns a boolean indicating whether the provided node is considered tabbable.
### tabbable.isFocusable
```
tabbable.isFocusable(node)
```
Returns a boolean indicating whether the provided node is considered *focusable*.
All tabbable elements are focusable, but not all focusable elements are tabbable. For example, elements with `tabindex="-1"` are focusable but not tabbable.
## More details
- **Tabbable tries to identify elements that are reliably tabbable across (not dead) browsers.** Browsers are stupidly inconsistent in their behavior, though — especially for edge-case elements like `<object>` and `<iframe>` — so this means *some* elements that you *can* tab to in *some* browsers will be left out of the results. (To learn more about that stupid inconsistency, see this [amazing table](https://allyjs.io/data-tables/focusable.html)). To provide better consistency across browsers and ensure the elements you *want* in your tabbables list show up there, **try adding `tabindex="0"` to edge-case elements that Tabbable ignores**.
- (Exemplifying the above ^^:) **The tabbability of `<iframe>`s, `<embed>`s, `<object>`s, and `<svg>`s is [inconsistent across browsers](https://allyjs.io/data-tables/focusable.html), so if you need an accurate read on one of these elements you should give it a `tabindex`. (You'll also need to pay attention to the `focusable` attribute on SVGs in IE & Edge.)
- (Exemplifying the above ^^:) **The tabbability of `<iframe>`s, `<embed>`s, `<object>`s, and `<svg>`s is [inconsistent across browsers](https://allyjs.io/data-tables/focusable.html)**, so if you need an accurate read on one of these elements you should try giving it a `tabindex`. (You'll also need to pay attention to the `focusable` attribute on SVGs in IE & Edge.) But you also might *not* be able to get an accurate read — so you should avoid relying on it.
- **Radio groups have some edge cases, which you can avoid by always having a `checked` one in each group** (and that is what you should usually do anyway). If there is no `checked` radio in the radio group, *all* of the radios will be considered tabbable. (Some browsers do this, otherwise don't — there's not consistency.)

@@ -90,3 +108,4 @@ - If you're thinking, "Why not just use the right `querySelectorAll`?", you *may* be on to something ... but, as with most "just" statements, you're probably not. For example, a simple `querySelectorAll` approach will not figure out whether an element is *hidden*, and therefore not actually tabbable. (That said, if you do think Tabbable can be simplified or otherwise improved, I'd love to hear your idea.)

- Although Tabbable tries to deal with positive tabindexes, **you should not use positive tabindexes**. Accessibility experts seem to be in (rare) unanimous and clear consent about this: rely on the order of elements in the document.
- Safari on Mac OS X does not Tab to `<a>` elements by default: you have to change a setting to get the standard behavior. Tabbable does not know whether you've changed that setting or not, so it will include `<a>` elements in its list.
***Feedback and contributions more than welcome!***
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