UNPKG

@chayns-components/core

Version:

A set of beautiful React components for developing your own applications with chayns.

238 lines (237 loc) • 9.88 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.shouldShowExpandIndicator = exports.isMarkedListItemElement = exports.isDirectListItemElement = exports.handleVerticalListGroupNavigation = exports.handleListItemToggleKey = exports.handleListItemTabNavigation = exports.handleHorizontalArrowNavigation = void 0; var _react = require("react"); var _ListItem = require("./list-item/ListItem.utils"); const isDirectListItemElement = node => /*#__PURE__*/(0, _react.isValidElement)(node) && node.type.displayName === 'ListItem'; exports.isDirectListItemElement = isDirectListItemElement; const isMarkedListItemElement = node => /*#__PURE__*/(0, _react.isValidElement)(node) && typeof node.type !== 'string' && node.type.$$listItem === _ListItem.LIST_ITEM_MARKER; exports.isMarkedListItemElement = isMarkedListItemElement; const shouldShowExpandIndicator = node => _react.Children.toArray(node).some(child => { if (isDirectListItemElement(child)) { return child.props.shouldHideIndicator !== true && child.props.children !== undefined; } if (isMarkedListItemElement(child)) { return child.props.isExpandable === true && child.props.shouldHideIndicator !== true; } if (/*#__PURE__*/(0, _react.isValidElement)(child) && child.props.children !== undefined) { return shouldShowExpandIndicator(child.props.children); } return false; }); exports.shouldShowExpandIndicator = shouldShowExpandIndicator; const LEFT_ELEMENT_FOCUSABLE_SELECTOR = '[data-left-element="true"] a[href], [data-left-element="true"] button, [data-left-element="true"] input, [data-left-element="true"] select, [data-left-element="true"] textarea, [data-left-element="true"] [tabindex], [data-left-element="true"] [contenteditable="true"]'; const RIGHT_ELEMENT_FOCUSABLE_SELECTOR = '[data-right-element="true"] a[href], [data-right-element="true"] button, [data-right-element="true"] input, [data-right-element="true"] select, [data-right-element="true"] textarea, [data-right-element="true"] [tabindex], [data-right-element="true"] [contenteditable="true"]'; const getFocusableElements = (root, selector) => Array.from(root.querySelectorAll(selector)).filter(element => !element.hasAttribute('disabled') && element.getAttribute('tabindex') !== '-1'); const getFocusedElementIndex = (elements, targetElement) => { if (!targetElement || elements.length === 0) { return -1; } return elements.findIndex(element => element === targetElement || element.contains(targetElement)); }; const getListItemElementByIndex = ({ index, listItemUuids, listGroupUuid }) => { const listItemUuid = listItemUuids[index]; if (!listItemUuid || typeof listGroupUuid !== 'string') { return undefined; } return document.querySelector(`[data-uuid="${listGroupUuid}---${listItemUuid}"]`); }; const focusListItemByIndex = ({ index, listItemUuids, listGroupUuid, updateActiveListItemUuid }) => { const listItemUuid = listItemUuids[index]; const listItemElement = getListItemElementByIndex({ index, listItemUuids, listGroupUuid }); if (!listItemUuid || !listItemElement || typeof updateActiveListItemUuid !== 'function') { return false; } updateActiveListItemUuid(listItemUuid); listItemElement.focus(); return true; }; const handleHorizontalArrowNavigation = ({ event, currentListItemElement, targetElement, isCurrentListItemTarget }) => { if (event.key !== 'ArrowRight' && event.key !== 'ArrowLeft') { return false; } const focusableLeftElements = getFocusableElements(currentListItemElement, LEFT_ELEMENT_FOCUSABLE_SELECTOR); const focusableRightElements = getFocusableElements(currentListItemElement, RIGHT_ELEMENT_FOCUSABLE_SELECTOR); const focusedLeftElementIndex = getFocusedElementIndex(focusableLeftElements, targetElement); if (focusedLeftElementIndex !== -1) { event.preventDefault(); if (event.key === 'ArrowLeft') { const previousLeftElement = focusableLeftElements[focusedLeftElementIndex - 1]; if (previousLeftElement) { previousLeftElement.focus(); } else { currentListItemElement.focus(); } return true; } const nextLeftElement = focusableLeftElements[focusedLeftElementIndex + 1]; if (nextLeftElement) { nextLeftElement.focus(); } else if (focusableRightElements.length > 0) { var _focusableRightElemen; (_focusableRightElemen = focusableRightElements[0]) === null || _focusableRightElemen === void 0 || _focusableRightElemen.focus(); } return true; } const focusedRightElementIndex = getFocusedElementIndex(focusableRightElements, targetElement); if (focusedRightElementIndex !== -1) { event.preventDefault(); if (event.key === 'ArrowRight') { var _focusableRightElemen2; (_focusableRightElemen2 = focusableRightElements[focusedRightElementIndex + 1]) === null || _focusableRightElemen2 === void 0 || _focusableRightElemen2.focus(); return true; } const previousRightElement = focusableRightElements[focusedRightElementIndex - 1]; if (previousRightElement) { previousRightElement.focus(); } else if (focusableLeftElements.length > 0) { var _focusableLeftElement; (_focusableLeftElement = focusableLeftElements[focusableLeftElements.length - 1]) === null || _focusableLeftElement === void 0 || _focusableLeftElement.focus(); } else { currentListItemElement.focus(); } return true; } if (isCurrentListItemTarget) { if (event.key === 'ArrowLeft' && focusableLeftElements.length > 0) { var _focusableLeftElement2; event.preventDefault(); (_focusableLeftElement2 = focusableLeftElements[focusableLeftElements.length - 1]) === null || _focusableLeftElement2 === void 0 || _focusableLeftElement2.focus(); return true; } if (event.key === 'ArrowRight' && focusableRightElements.length > 0) { var _focusableRightElemen3; event.preventDefault(); (_focusableRightElemen3 = focusableRightElements[0]) === null || _focusableRightElemen3 === void 0 || _focusableRightElemen3.focus(); return true; } } return false; }; exports.handleHorizontalArrowNavigation = handleHorizontalArrowNavigation; const handleListItemTabNavigation = ({ event, currentListItemElement, targetElement, isCurrentListItemTarget, isInKeyboardNavigationGroup, listItemUuids, currentUuid, listGroupUuid, updateActiveListItemUuid }) => { if (event.key !== 'Tab' || !isInKeyboardNavigationGroup || !(listItemUuids !== null && listItemUuids !== void 0 && listItemUuids.length)) { return false; } const currentIndex = listItemUuids.indexOf(currentUuid); if (currentIndex === -1) { return false; } const focusableRightElements = getFocusableElements(currentListItemElement, RIGHT_ELEMENT_FOCUSABLE_SELECTOR); const focusedRightElementIndex = getFocusedElementIndex(focusableRightElements, targetElement); if (event.shiftKey) { return false; } if (isCurrentListItemTarget) { if (focusableRightElements.length > 0) { var _focusableRightElemen4; event.preventDefault(); (_focusableRightElemen4 = focusableRightElements[0]) === null || _focusableRightElemen4 === void 0 || _focusableRightElemen4.focus(); return true; } return false; } if (focusedRightElementIndex === -1) { return false; } const nextRightElement = focusableRightElements[focusedRightElementIndex + 1]; if (nextRightElement) { event.preventDefault(); nextRightElement.focus(); return true; } if (currentIndex < listItemUuids.length - 1) { event.preventDefault(); return focusListItemByIndex({ index: currentIndex + 1, listItemUuids, listGroupUuid, updateActiveListItemUuid }); } return false; }; exports.handleListItemTabNavigation = handleListItemTabNavigation; const handleVerticalListGroupNavigation = ({ event, isCurrentListItemTarget, isInKeyboardNavigationGroup, listItemUuids, currentUuid, listGroupUuid, updateActiveListItemUuid }) => { if (!isCurrentListItemTarget || !isInKeyboardNavigationGroup || !(listItemUuids !== null && listItemUuids !== void 0 && listItemUuids.length) || event.key !== 'ArrowDown' && event.key !== 'ArrowUp') { return false; } const currentIndex = listItemUuids.indexOf(currentUuid); if (currentIndex === -1) { return true; } const isBackward = event.key === 'ArrowUp'; event.preventDefault(); const nextIndex = isBackward ? (currentIndex - 1 + listItemUuids.length) % listItemUuids.length : (currentIndex + 1) % listItemUuids.length; const nextListItemUuid = listItemUuids[nextIndex]; if (nextListItemUuid && nextListItemUuid !== currentUuid && typeof listGroupUuid === 'string' && typeof updateActiveListItemUuid === 'function') { const nextListItemElement = document.querySelector(`[data-uuid="${listGroupUuid}---${nextListItemUuid}"]`); if (nextListItemElement) { updateActiveListItemUuid(nextListItemUuid); nextListItemElement.focus(); } } return true; }; exports.handleVerticalListGroupNavigation = handleVerticalListGroupNavigation; const handleListItemToggleKey = ({ event, isCurrentListItemTarget, isExpandable, isItemOpen, shouldEnableKeyboardHighlighting, toggleItem }) => { if (!isCurrentListItemTarget || !shouldEnableKeyboardHighlighting) { return false; } const shouldOpen = isExpandable && event.key === 'ArrowRight' && !isItemOpen; const shouldClose = isExpandable && event.key === 'ArrowLeft' && isItemOpen; const shouldToggle = event.key === 'Enter' || event.key === ' '; if (!shouldOpen && !shouldClose && !shouldToggle) { return false; } event.preventDefault(); toggleItem(); return true; }; exports.handleListItemToggleKey = handleListItemToggleKey; //# sourceMappingURL=List.utils.js.map