diff --git a/packages/dom/README.md b/packages/dom/README.md
index d52e47552f342..12a3eb3f49d2c 100644
--- a/packages/dom/README.md
+++ b/packages/dom/README.md
@@ -52,7 +52,7 @@ _Parameters_
_Returns_
-- `?Node`: Offset parent.
+- `(Element|null)`: Offset parent.
# **getRectangleFromRange**
@@ -68,15 +68,15 @@ _Returns_
# **getScrollContainer**
-Given a DOM node, finds the closest scrollable container node.
+Given a DOM element, finds the closest scrollable container element.
_Parameters_
-- _node_ `Element`: Node from which to start.
+- _element_ `Element`: Element from which to start.
_Returns_
-- `?Element`: Scrollable container node, if found.
+- `(Element|undefined)`: Scrollable container node, if found.
# **insertAfter**
@@ -85,12 +85,8 @@ the latter.
_Parameters_
-- _newNode_ `Element`: Node to be inserted.
-- _referenceNode_ `Element`: Node after which to perform the insertion.
-
-_Returns_
-
-- `void`:
+- _newNode_ `Node`: Node to be inserted.
+- _referenceNode_ `Node`: Node after which to perform the insertion.
# **isEntirelySelected**
@@ -99,7 +95,7 @@ Returns true if there is no possibility of selection.
_Parameters_
-- _element_ `Element`: The element to check.
+- _element_ `HTMLElement`: The element to check.
_Returns_
@@ -111,7 +107,7 @@ Check whether the selection is horizontally at the edge of the container.
_Parameters_
-- _container_ `Element`: Focusable element.
+- _container_ `HTMLElement`: Focusable element.
- _isReverse_ `boolean`: Set to true to check left, false for right.
_Returns_
@@ -139,7 +135,7 @@ Check whether the selection is vertically at the edge of the container.
_Parameters_
-- _container_ `Element`: Focusable element.
+- _container_ `HTMLElement`: Focusable element.
- _isReverse_ `boolean`: Set to true to check top, false for bottom.
_Returns_
@@ -152,7 +148,7 @@ Places the caret at start or end of a given element.
_Parameters_
-- _container_ `Element`: Focusable element.
+- _container_ `(HTMLElement|undefined)`: Focusable element.
- _isReverse_ `boolean`: True for end, false for start.
# **placeCaretAtVerticalEdge**
@@ -161,7 +157,7 @@ Places the caret at the top or bottom of a given element.
_Parameters_
-- _container_ `Element`: Focusable element.
+- _container_ `(HTMLElement|undefined)`: Focusable element.
- _isReverse_ `boolean`: True for bottom, false for top.
- _rect_ `[DOMRect]`: The rectangle to position the caret with.
- _mayUseScroll_ `[boolean]`: True to allow scrolling, false to disallow.
@@ -172,11 +168,7 @@ Given a DOM node, removes it from the DOM.
_Parameters_
-- _node_ `Element`: Node to be removed.
-
-_Returns_
-
-- `void`:
+- _node_ `Node`: Node to be removed.
# **replace**
@@ -184,12 +176,8 @@ Given two DOM nodes, replaces the former with the latter in the DOM.
_Parameters_
-- _processedNode_ `Element`: Node to be removed.
-- _newNode_ `Element`: Node to be inserted in its place.
-
-_Returns_
-
-- `void`:
+- _processedNode_ `Node`: Node to be removed.
+- _newNode_ `Node`: Node to be inserted in its place.
# **replaceTag**
@@ -197,12 +185,12 @@ Replaces the given node with a new node with the given tag name.
_Parameters_
-- _node_ `Element`: The node to replace
-- _tagName_ `string`: The new tag name.
+- _node_ `Node`: The node to replace.
+- _tagName_ `T`: The new tag name.
_Returns_
-- `Element`: The new node.
+- `null`: The new node.
# **unwrap**
@@ -212,18 +200,14 @@ _Parameters_
- _node_ `Node`: The node to unwrap.
-_Returns_
-
-- `void`:
-
# **wrap**
Wraps the given node with a new node with the given tag name.
_Parameters_
-- _newNode_ `Element`: The node to insert.
-- _referenceNode_ `Element`: The node to wrap.
+- _newNode_ `Node`: The node to insert.
+- _referenceNode_ `Node`: The node to wrap.
diff --git a/packages/dom/src/dom.js b/packages/dom/src/dom.js
index 64fb97534f60a..901d2405c8622 100644
--- a/packages/dom/src/dom.js
+++ b/packages/dom/src/dom.js
@@ -64,9 +64,9 @@ function isSelectionForward( selection ) {
* horizontal position by default. Set `onlyVertical` to true to check only
* vertically.
*
- * @param {Element} container Focusable element.
- * @param {boolean} isReverse Set to true to check left, false to check right.
- * @param {boolean} onlyVertical Set to true to check only vertical position.
+ * @param {HTMLElement} container Focusable element.
+ * @param {boolean} isReverse Set to true to check left, false to check right.
+ * @param {boolean} onlyVertical Set to true to check only vertical position.
*
* @return {boolean} True if at the edge, false if not.
*/
@@ -169,8 +169,8 @@ function isEdge( container, isReverse, onlyVertical ) {
/**
* Check whether the selection is horizontally at the edge of the container.
*
- * @param {Element} container Focusable element.
- * @param {boolean} isReverse Set to true to check left, false for right.
+ * @param {HTMLElement} container Focusable element.
+ * @param {boolean} isReverse Set to true to check left, false for right.
*
* @return {boolean} True if at the horizontal edge, false if not.
*/
@@ -181,7 +181,7 @@ export function isHorizontalEdge( container, isReverse ) {
/**
* Check whether the selection is vertically at the edge of the container.
*
- * @param {Element} container Focusable element.
+ * @param {HTMLElement} container Focusable element.
* @param {boolean} isReverse Set to true to check top, false for bottom.
*
* @return {boolean} True if at the vertical edge, false if not.
@@ -255,8 +255,8 @@ export function computeCaretRect() {
/**
* Places the caret at start or end of a given element.
*
- * @param {Element} container Focusable element.
- * @param {boolean} isReverse True for end, false for start.
+ * @param {HTMLElement|undefined} container Focusable element.
+ * @param {boolean} isReverse True for end, false for start.
*/
export function placeCaretAtHorizontalEdge( container, isReverse ) {
if ( ! container ) {
@@ -364,10 +364,10 @@ function hiddenCaretRangeFromPoint( doc, x, y, container ) {
/**
* Places the caret at the top or bottom of a given element.
*
- * @param {Element} container Focusable element.
- * @param {boolean} isReverse True for bottom, false for top.
- * @param {DOMRect} [rect] The rectangle to position the caret with.
- * @param {boolean} [mayUseScroll=true] True to allow scrolling, false to disallow.
+ * @param {HTMLElement|undefined} container Focusable element.
+ * @param {boolean} isReverse True for bottom, false for top.
+ * @param {DOMRect} [rect] The rectangle to position the caret with.
+ * @param {boolean} [mayUseScroll=true] True to allow scrolling, false to disallow.
*/
export function placeCaretAtVerticalEdge( container, isReverse, rect, mayUseScroll = true ) {
if ( ! container ) {
@@ -484,7 +484,7 @@ export function documentHasSelection() {
* Check whether the contents of the element have been entirely selected.
* Returns true if there is no possibility of selection.
*
- * @param {Element} element The element to check.
+ * @param {HTMLElement} element The element to check.
*
* @return {boolean} True if entirely selected, false if not.
*/
@@ -529,28 +529,28 @@ export function isEntirelySelected( element ) {
}
/**
- * Given a DOM node, finds the closest scrollable container node.
+ * Given a DOM element, finds the closest scrollable container element.
*
- * @param {Element} node Node from which to start.
+ * @param {Element} element Element from which to start.
*
- * @return {?Element} Scrollable container node, if found.
+ * @return {Element|undefined} Scrollable container node, if found.
*/
-export function getScrollContainer( node ) {
- if ( ! node ) {
+export function getScrollContainer( element ) {
+ if ( ! element ) {
return;
}
// Scrollable if scrollable height exceeds displayed...
- if ( node.scrollHeight > node.clientHeight ) {
+ if ( element.scrollHeight > element.clientHeight ) {
// ...except when overflow is defined to be hidden or visible
- const { overflowY } = window.getComputedStyle( node );
+ const { overflowY } = window.getComputedStyle( element );
if ( /(auto|scroll)/.test( overflowY ) ) {
- return node;
+ return element;
}
}
// Continue traversing
- return getScrollContainer( node.parentNode );
+ return getScrollContainer( element.parentElement );
}
/**
@@ -562,7 +562,7 @@ export function getScrollContainer( node ) {
*
* @param {Node} node Node from which to find offset parent.
*
- * @return {?Node} Offset parent.
+ * @return {Element|null} Offset parent.
*/
export function getOffsetParent( node ) {
// Cannot retrieve computed style or offset parent only anything other than
@@ -590,9 +590,8 @@ export function getOffsetParent( node ) {
/**
* Given two DOM nodes, replaces the former with the latter in the DOM.
*
- * @param {Element} processedNode Node to be removed.
- * @param {Element} newNode Node to be inserted in its place.
- * @return {void}
+ * @param {Node} processedNode Node to be removed.
+ * @param {Node} newNode Node to be inserted in its place.
*/
export function replace( processedNode, newNode ) {
insertAfter( newNode, processedNode.parentNode );
@@ -602,8 +601,7 @@ export function replace( processedNode, newNode ) {
/**
* Given a DOM node, removes it from the DOM.
*
- * @param {Element} node Node to be removed.
- * @return {void}
+ * @param {Node} node Node to be removed.
*/
export function remove( node ) {
node.parentNode.removeChild( node );
@@ -613,9 +611,8 @@ export function remove( node ) {
* Given two DOM nodes, inserts the former in the DOM as the next sibling of
* the latter.
*
- * @param {Element} newNode Node to be inserted.
- * @param {Element} referenceNode Node after which to perform the insertion.
- * @return {void}
+ * @param {Node} newNode Node to be inserted.
+ * @param {Node} referenceNode Node after which to perform the insertion.
*/
export function insertAfter( newNode, referenceNode ) {
referenceNode.parentNode.insertBefore( newNode, referenceNode.nextSibling );
@@ -625,8 +622,6 @@ export function insertAfter( newNode, referenceNode ) {
* Unwrap the given node. This means any child nodes are moved to the parent.
*
* @param {Node} node The node to unwrap.
- *
- * @return {void}
*/
export function unwrap( node ) {
const parent = node.parentNode;
@@ -638,13 +633,15 @@ export function unwrap( node ) {
parent.removeChild( node );
}
+// eslint-disable-next-line valid-jsdoc
/**
* Replaces the given node with a new node with the given tag name.
*
- * @param {Element} node The node to replace
- * @param {string} tagName The new tag name.
+ * @template {keyof HTMLElementTagNameMap} T
+ * @param {Node} node The node to replace.
+ * @param {T} tagName The new tag name.
*
- * @return {Element} The new node.
+ * @return {HTMLElementTagNameMap[T]} The new node.
*/
export function replaceTag( node, tagName ) {
const newNode = node.ownerDocument.createElement( tagName );
@@ -661,8 +658,8 @@ export function replaceTag( node, tagName ) {
/**
* Wraps the given node with a new node with the given tag name.
*
- * @param {Element} newNode The node to insert.
- * @param {Element} referenceNode The node to wrap.
+ * @param {Node} newNode The node to insert.
+ * @param {Node} referenceNode The node to wrap.
*/
export function wrap( newNode, referenceNode ) {
referenceNode.parentNode.insertBefore( newNode, referenceNode );
diff --git a/packages/dom/src/focusable.js b/packages/dom/src/focusable.js
index 133b89d366974..0491741c1b231 100644
--- a/packages/dom/src/focusable.js
+++ b/packages/dom/src/focusable.js
@@ -35,7 +35,7 @@ const SELECTOR = [
* Returns true if the specified element is visible (i.e. neither display: none
* nor visibility: hidden).
*
- * @param {Element} element DOM element to test.
+ * @param {HTMLElement} element DOM element to test.
*
* @return {boolean} Whether element is visible.
*/
@@ -69,7 +69,7 @@ function isValidFocusableArea( element ) {
/**
* Returns all focusable elements within a given context.
*
- * @param {Element} context Element in which to search.
+ * @param {ParentNode} context Element in which to search.
*
* @return {Element[]} Focusable elements.
*/
diff --git a/packages/dom/src/tabbable.js b/packages/dom/src/tabbable.js
index 315a98b8b2a8e..8cac26ac5178e 100644
--- a/packages/dom/src/tabbable.js
+++ b/packages/dom/src/tabbable.js
@@ -8,6 +8,12 @@ import { without } from 'lodash';
*/
import { find as findFocusable } from './focusable';
+/**
+ * @typedef {Object} ObjectTabbable
+ * @prop {Element} element Element to be indexed.
+ * @prop {number} index Index of the element.
+ */
+
/**
* Returns the tab index of the given element. In contrast with the tabIndex
* property, this normalizes the default (0) to avoid browser inconsistencies,
@@ -86,7 +92,7 @@ function createStatefulCollapseRadioGroup() {
* @param {Element} element Element.
* @param {number} index Array index of element.
*
- * @return {Object} Mapped object with element, index.
+ * @return {ObjectTabbable} Mapped object with element, index.
*/
function mapElementToObjectTabbable( element, index ) {
return { element, index };
@@ -96,7 +102,7 @@ function mapElementToObjectTabbable( element, index ) {
* An array map callback, returning an element of the given mapped object's
* element value.
*
- * @param {Object} object Mapped object with index.
+ * @param {ObjectTabbable} object Mapped object with index.
*
* @return {Element} Mapped object element.
*/
@@ -109,8 +115,8 @@ function mapObjectTabbableToElement( object ) {
*
* @see mapElementToObjectTabbable
*
- * @param {Object} a First object to compare.
- * @param {Object} b Second object to compare.
+ * @param {ObjectTabbable} a First object to compare.
+ * @param {ObjectTabbable} b Second object to compare.
*
* @return {number} Comparator result.
*/
@@ -125,6 +131,15 @@ function compareObjectTabbables( a, b ) {
return aTabIndex - bTabIndex;
}
+/**
+ * Returns a filtered array of tabbable elements, where at most one radio
+ * input is selected for a given name, giving priority to checked input,
+ * falling back to the first encountered.
+ *
+ * @param {ParentNode} context Element in which to search.
+ *
+ * @return {Element[]} Tabbable elements.
+ */
export function find( context ) {
return findFocusable( context )
.filter( isTabbableIndex )