@blocklet/payment-react
Version:
Reusable react components for payment kit v2
88 lines (87 loc) • 3.18 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useTabNavigation = void 0;
var _react = require("react");
const useTabNavigation = (items, onSelect, options) => {
const {
valueType = "value",
includeCustom = false,
currentValue,
isCustomSelected = false,
compareValue = (item, value) => item === value,
enabled = true,
selector = ".tab-navigable-card button",
containerRef
} = options || {};
const hasTabbed = (0, _react.useRef)(false);
const findNavigableElements = (0, _react.useCallback)(() => {
if (containerRef?.current) {
return containerRef.current.querySelectorAll(selector);
}
return document.querySelectorAll(selector);
}, [containerRef, selector]);
const determineCurrentIndex = (0, _react.useCallback)(() => {
const allOptions = includeCustom ? [...items, "custom"] : items;
if (allOptions.length === 0) return -1;
if (!hasTabbed.current) {
if (isCustomSelected && includeCustom) {
return items.length;
}
if (currentValue !== void 0) {
if (valueType === "index" && typeof currentValue === "number") {
return currentValue >= 0 && currentValue < items.length ? currentValue : -1;
}
return items.findIndex(item => compareValue(item, currentValue));
}
} else {
const focusedElement = document.activeElement;
const navigableElements = findNavigableElements();
for (let i = 0; i < navigableElements.length; i++) {
if (navigableElements[i] === focusedElement) {
return i;
}
}
if (includeCustom && navigableElements.length > 0) {
return navigableElements.length - 1;
}
}
return -1;
}, [items, includeCustom, isCustomSelected, currentValue, valueType, compareValue, findNavigableElements]);
const getNextIndex = (0, _react.useCallback)((currentIndex, isShiftKey) => {
const totalOptions = includeCustom ? items.length + 1 : items.length;
if (currentIndex === -1) {
return 0;
}
if (isShiftKey) {
return currentIndex === 0 ? totalOptions - 1 : currentIndex - 1;
}
return currentIndex === totalOptions - 1 ? 0 : currentIndex + 1;
}, [items, includeCustom]);
const handleKeyDown = (0, _react.useCallback)(e => {
if (!enabled || e.key !== "Tab") return;
e.preventDefault();
e.stopPropagation();
const currentIndex = determineCurrentIndex();
const nextIndex = getNextIndex(currentIndex, e.shiftKey);
hasTabbed.current = true;
const selectedItem = nextIndex === items.length ? "custom" : items[nextIndex];
onSelect(selectedItem, nextIndex);
setTimeout(() => {
const elements = findNavigableElements();
if (elements[nextIndex]) {
elements[nextIndex].focus();
}
}, 0);
}, [items, onSelect, enabled, determineCurrentIndex, getNextIndex, findNavigableElements]);
const resetTabNavigation = (0, _react.useCallback)(() => {
hasTabbed.current = false;
}, []);
return {
handleKeyDown,
resetTabNavigation,
isTabNavigationActive: hasTabbed.current
};
};
exports.useTabNavigation = useTabNavigation;