UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

111 lines (110 loc) 3.49 kB
"use client"; import { useEffect, useRef } from 'react'; function useHandleCursorPosition(inputRefs, keysToHandle) { const inputList = useRef(refsToInputList(inputRefs)); useEffect(() => { inputList.current = refsToInputList(inputRefs); }, [inputRefs]); function onKeyDown(event) { var _getKeysToHandle; const inputs = inputList.current; const input = event.target; const pressedKey = event.key; const hasPressedKeysToHandle = ((_getKeysToHandle = getKeysToHandle({ keysToHandle, input })) === null || _getKeysToHandle === void 0 ? void 0 : _getKeysToHandle.test(pressedKey)) || /(ArrowRight|ArrowLeft|Backspace)/.test(pressedKey); const hasSelection = hasSelectedValue(input); const inputPosition = !hasSelection && getInputPosition(input, inputs); const initialSelectionStart = input.selectionStart; window.requestAnimationFrame(() => { if (!hasPressedKeysToHandle || hasSelection) { return; } const caretPosition = getCaretPosition(input); if (caretPosition === 'last' && inputPosition !== 'last' && !(initialSelectionStart === 1 && pressedKey === 'ArrowRight')) { return goToInput('next', input, inputs); } if (caretPosition === 'first' && inputPosition !== 'first' && !(initialSelectionStart === 1 && (pressedKey === 'ArrowLeft' || pressedKey === 'Backspace'))) { return goToInput('previous', input, inputs); } }); } return { onKeyDown }; } function refsToInputList(inputRefs) { return inputRefs.map(ref => ref.current).filter(Boolean); } function getKeysToHandle({ keysToHandle, input }) { if (!keysToHandle) { return undefined; } if (keysToHandle instanceof RegExp) { return keysToHandle; } const masks = keysToHandle[input.dataset.maskId]; const selection = input.selectionStart === input.selectionEnd ? input.selectionStart : undefined; if (!selection) { return undefined; } const maskIndex = selection === input.size ? masks.length - 1 : selection; return masks[maskIndex]; } function getInputPosition(input, inputs) { const firstInput = inputs[0]; const lastInput = inputs[inputs.length - 1]; if (input === firstInput) { return 'first'; } if (input === lastInput) { return 'last'; } return 'non-initial'; } function getSelectionPositions(input) { return { start: 0, end: Number(input.size) }; } function hasSelectedValue(input) { return input.selectionEnd > input.selectionStart; } function getCaretPosition(input) { const { start, end } = getSelectionPositions(input); const selectionStart = input.selectionStart; const selectionEnd = input.selectionEnd; if (selectionStart === start && selectionEnd === start) { return 'first'; } if (selectionStart === end && selectionEnd === end) { return 'last'; } return 'non-initial'; } function goToInput(to, input, inputs) { const currentInputIndex = inputs.indexOf(input); const siblingIndex = to === 'next' ? currentInputIndex + 1 : to === 'previous' ? currentInputIndex - 1 : 0; const siblingInput = inputs[siblingIndex]; const { start, end } = getSelectionPositions(siblingInput); siblingInput.focus(); if (to === 'next') { return siblingInput.setSelectionRange(start, start); } if (to === 'previous') { return siblingInput.setSelectionRange(end, end); } } export default useHandleCursorPosition; //# sourceMappingURL=useHandleCursorPosition.js.map