@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
111 lines (110 loc) • 3.49 kB
JavaScript
"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