UNPKG

@blocklet/payment-react

Version:

Reusable react components for payment kit v2

88 lines (87 loc) 3.18 kB
"use strict"; 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;