File size: 3,607 Bytes
bc20498 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
import { isAnySegmentPart } from '../../../builders/date-field/_internal/helpers.js';
import { isHTMLElement, kbd } from '../index.js';
/**
* Handles segment navigation based on the provided keyboard event and field ID.
*
* @param e - The keyboard event
* @param fieldId - The ID of the field we're navigating within
*/
export function handleSegmentNavigation(e, fieldId) {
const currentTarget = e.currentTarget;
if (!isHTMLElement(currentTarget))
return;
const { prev, next } = getPrevNextSegments(currentTarget, fieldId);
if (e.key === kbd.ARROW_LEFT) {
if (!prev)
return;
prev.focus();
}
else if (e.key === kbd.ARROW_RIGHT) {
if (!next)
return;
next.focus();
}
}
/**
* Retrieves the next segment in the list of segments relative to the provided node.
*
* @param node - The node we're starting from
* @param segments - The list of candidate segments to navigate through
*/
export function getNextSegment(node, segments) {
const index = segments.indexOf(node);
if (index === segments.length - 1 || index === -1)
return null;
const nextIndex = index + 1;
const nextSegment = segments[nextIndex];
return nextSegment;
}
/**
* Retrieves the previous segment in the list of segments relative to the provided node.
*
* @param node - The node we're starting from
* @param segments - The list of candidate segments to navigate through
*/
export function getPrevSegment(node, segments) {
const index = segments.indexOf(node);
if (index === 0 || index === -1)
return null;
const prevIndex = index - 1;
const prevSegment = segments[prevIndex];
return prevSegment;
}
/**
* Retrieves an object containing the next and previous segments relative to the current node.
*
* @param node - The node we're starting from
* @param fieldId - The ID of the field we're navigating within
*/
export function getPrevNextSegments(node, fieldId) {
const segments = getSegments(fieldId);
if (!segments.length) {
return {
next: null,
prev: null,
};
}
return {
next: getNextSegment(node, segments),
prev: getPrevSegment(node, segments),
};
}
/**
* Shifts the focus to the next segment in the list of segments
* within the field identified by the provided ID.
*/
export function moveToNextSegment(e, fieldId) {
const node = e.currentTarget;
if (!isHTMLElement(node))
return;
const { next } = getPrevNextSegments(node, fieldId);
if (!next)
return;
next.focus();
}
export function isSegmentNavigationKey(key) {
if (key === kbd.ARROW_RIGHT || key === kbd.ARROW_LEFT)
return true;
return false;
}
/**
* Retrieves all the interactive segments within the field identified by the provided ID.
*/
export function getSegments(id) {
const inputContainer = document.getElementById(id);
if (!isHTMLElement(inputContainer))
return [];
const segments = Array.from(inputContainer.querySelectorAll('[data-segment]')).filter((el) => {
if (!isHTMLElement(el))
return false;
const segment = el.dataset.segment;
if (segment === 'trigger')
return true;
if (!isAnySegmentPart(segment) || segment === 'literal')
return false;
return true;
});
return segments;
}
/**
* Get the first interactive segment within the field identified by the provided ID.
*/
export function getFirstSegment(id) {
const segments = getSegments(id);
return segments[0];
}
|