@chayns-components/core
Version:
A set of beautiful React components for developing your own applications with chayns.
238 lines (237 loc) • 9.88 kB
JavaScript
;
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