diff options
author | GeoSot <geo.sotis@gmail.com> | 2021-05-19 01:23:52 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-19 01:23:52 +0300 |
commit | df72a21fa89a4885bb666f4a3bc0a9e757b870c2 (patch) | |
tree | d80c2614184e53f73de9364ac46dbeef9f61aa08 /js/src | |
parent | 372890b67b28238c98ec4d5ffcdb777c9939e87c (diff) |
Add `getNextActiveElement` helper function to utils, replacing custom implementation through components (#33608)
Diffstat (limited to 'js/src')
-rw-r--r-- | js/src/carousel.js | 17 | ||||
-rw-r--r-- | js/src/dropdown.js | 22 | ||||
-rw-r--r-- | js/src/util/index.js | 29 |
3 files changed, 37 insertions, 31 deletions
diff --git a/js/src/carousel.js b/js/src/carousel.js index bb894e9c37..7d197ab1ee 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -10,6 +10,7 @@ import { getElementFromSelector, isRTL, isVisible, + getNextActiveElement, reflow, triggerTransitionEnd, typeCheckConfig @@ -337,21 +338,7 @@ class Carousel extends BaseComponent { _getItemByOrder(order, activeElement) { const isNext = order === ORDER_NEXT - const isPrev = order === ORDER_PREV - const activeIndex = this._getItemIndex(activeElement) - const lastItemIndex = this._items.length - 1 - const isGoingToWrap = (isPrev && activeIndex === 0) || (isNext && activeIndex === lastItemIndex) - - if (isGoingToWrap && !this._config.wrap) { - return activeElement - } - - const delta = isPrev ? -1 : 1 - const itemIndex = (activeIndex + delta) % this._items.length - - return itemIndex === -1 ? - this._items[this._items.length - 1] : - this._items[itemIndex] + return getNextActiveElement(this._items, activeElement, isNext, this._config.wrap) } _triggerSlideEvent(relatedTarget, eventDirectionName) { diff --git a/js/src/dropdown.js b/js/src/dropdown.js index 565edb8929..cab2d018bb 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -16,6 +16,7 @@ import { isVisible, isRTL, noop, + getNextActiveElement, typeCheckConfig } from './util/index' import Data from './dom/data' @@ -354,28 +355,17 @@ class Dropdown extends BaseComponent { } _selectMenuItem(event) { - const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(isVisible) - - if (!items.length) { + if (![ARROW_UP_KEY, ARROW_DOWN_KEY].includes(event.key)) { return } - let index = items.indexOf(event.target) - - // Up - if (event.key === ARROW_UP_KEY && index > 0) { - index-- - } + const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(isVisible) - // Down - if (event.key === ARROW_DOWN_KEY && index < items.length - 1) { - index++ + if (!items.length) { + return } - // index is -1 if the first keydown is an ArrowUp - index = index === -1 ? 0 : index - - items[index].focus() + getNextActiveElement(items, event.target, event.key === ARROW_DOWN_KEY, false).focus() } // Static diff --git a/js/src/util/index.js b/js/src/util/index.js index 9441d0a44a..6b38a05e94 100644 --- a/js/src/util/index.js +++ b/js/src/util/index.js @@ -261,6 +261,34 @@ const execute = callback => { } } +/** + * Return the previous/next element of a list. + * + * @param {array} list The list of elements + * @param activeElement The active element + * @param shouldGetNext Choose to get next or previous element + * @param isCycleAllowed + * @return {Element|elem} The proper element + */ +const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => { + let index = list.indexOf(activeElement) + + // if the element does not exist in the list initialize it as the first element + if (index === -1) { + return list[0] + } + + const listLength = list.length + + index += shouldGetNext ? 1 : -1 + + if (isCycleAllowed) { + index = (index + listLength) % listLength + } + + return list[Math.max(0, Math.min(index, listLength - 1))] +} + export { getElement, getUID, @@ -275,6 +303,7 @@ export { isDisabled, findShadowRoot, noop, + getNextActiveElement, reflow, getjQuery, onDOMContentLoaded, |