diff --git a/packages/dom/README.md b/packages/dom/README.md index 4a2fc100174e13..f87ccbb3ac731e 100644 --- a/packages/dom/README.md +++ b/packages/dom/README.md @@ -131,6 +131,7 @@ Given a DOM node, finds the closest scrollable container node or the node itself _Parameters_ - _node_ `Element | null`: Node from which to start. +- _direction_ `?string`: Direction of scrollable container to search for ('vertical', 'horizontal', 'all'). Defaults to 'vertical'. _Returns_ diff --git a/packages/dom/src/dom/get-scroll-container.js b/packages/dom/src/dom/get-scroll-container.js index 6c472e6195496a..da46f23c660ba2 100644 --- a/packages/dom/src/dom/get-scroll-container.js +++ b/packages/dom/src/dom/get-scroll-container.js @@ -7,22 +7,37 @@ import getComputedStyle from './get-computed-style'; * Given a DOM node, finds the closest scrollable container node or the node * itself, if scrollable. * - * @param {Element | null} node Node from which to start. - * + * @param {Element | null} node Node from which to start. + * @param {?string} direction Direction of scrollable container to search for ('vertical', 'horizontal', 'all'). + * Defaults to 'vertical'. * @return {Element | undefined} Scrollable container node, if found. */ -export default function getScrollContainer( node ) { +export default function getScrollContainer( node, direction = 'vertical' ) { if ( ! node ) { return undefined; } - // Scrollable if scrollable height exceeds displayed... - if ( node.scrollHeight > node.clientHeight ) { - // ...except when overflow is defined to be hidden or visible - const { overflowY } = getComputedStyle( node ); + if ( direction === 'vertical' || direction === 'all' ) { + // Scrollable if scrollable height exceeds displayed... + if ( node.scrollHeight > node.clientHeight ) { + // ...except when overflow is defined to be hidden or visible + const { overflowY } = getComputedStyle( node ); + + if ( /(auto|scroll)/.test( overflowY ) ) { + return node; + } + } + } + + if ( direction === 'horizontal' || direction === 'all' ) { + // Scrollable if scrollable width exceeds displayed... + if ( node.scrollWidth > node.clientWidth ) { + // ...except when overflow is defined to be hidden or visible + const { overflowX } = getComputedStyle( node ); - if ( /(auto|scroll)/.test( overflowY ) ) { - return node; + if ( /(auto|scroll)/.test( overflowX ) ) { + return node; + } } } @@ -31,5 +46,8 @@ export default function getScrollContainer( node ) { } // Continue traversing. - return getScrollContainer( /** @type {Element} */ ( node.parentNode ) ); + return getScrollContainer( + /** @type {Element} */ ( node.parentNode ), + direction + ); }