UNPKG

vuetify

Version:

Vue Material Component Framework

64 lines (63 loc) 2.45 kB
// Utilities import { toValue } from 'vue'; import { focusableChildren } from "../util/index.js"; // Types export function useFocusGroups({ groups, onLeave }) { function getContentRef(group) { return group.type === 'list' ? group.contentRef.value?.$el : group.contentRef.value; } function getChildren(group) { const contentRef = getContentRef(group); return contentRef ? focusableChildren(contentRef) : []; } function onTabKeydown(e) { const target = e.target; const direction = e.shiftKey ? 'backward' : 'forward'; const children = groups.map(getChildren); const currentGroupIndex = groups.map(g => g.type === 'list' ? g.contentRef.value?.$el : g.contentRef.value).findIndex(el => el?.contains(target)); const nextIndex = nextFocusGroup(children, currentGroupIndex, direction, target); if (nextIndex === null) { const originGroup = groups[currentGroupIndex]; const origin = children[currentGroupIndex]; const isListGroup = originGroup.type === 'list'; const atEdge = isListGroup || (direction === 'forward' ? origin.at(-1) === e.target : origin.at(0) === e.target); if (atEdge) { onLeave(); } } else { e.preventDefault(); e.stopImmediatePropagation(); const nextGroup = groups[nextIndex]; if (nextGroup.type === 'list' && toValue(nextGroup.displayItemsCount) > 0) { nextGroup.contentRef.value?.focus(0); } else { const fromBefore = direction === 'forward'; children[nextIndex].at(fromBefore ? 0 : -1).focus(); } } } function nextFocusGroup(children, currentIndex, direction, target) { const originGroup = groups[currentIndex]; const origin = children[currentIndex]; // List groups always allow leaving (VList manages internal focus) // Element groups require being at the edge focusable child if (originGroup.type !== 'list') { const isAtEdge = direction === 'forward' ? origin.at(-1) === target : origin.at(0) === target; if (!isAtEdge) return null; } const step = direction === 'forward' ? 1 : -1; for (let i = currentIndex + step; i >= 0 && i < groups.length; i += step) { const group = groups[i]; if (children[i].length > 0 || group.type === 'list' && toValue(group.displayItemsCount) > 0) { return i; } } return null; } return { onTabKeydown }; } //# sourceMappingURL=focusGroups.js.map