UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

179 lines 5.77 kB
import { useCallback } from 'react'; function useHandleCursorPosition(keysToHandle, scopeRootRef, options) { const onKeyDown = useCallback(event => { var _input$selectionStart, _input$selectionEnd; const input = event.target; const key = event.key; const size = getInputVisualSize(input); const placeholder = input.placeholder || ''; const typedLen = getTypedLengthBasic(input.value || '', placeholder, size); const selStart = (_input$selectionStart = input.selectionStart) !== null && _input$selectionStart !== void 0 ? _input$selectionStart : 0; const selEnd = (_input$selectionEnd = input.selectionEnd) !== null && _input$selectionEnd !== void 0 ? _input$selectionEnd : selStart; const hasSelection = selStart !== selEnd; const atStart = selStart === 0 && selEnd === 0; const atEnd = selStart === size && selEnd === size; const allInputs = listAllInputs((scopeRootRef === null || scopeRootRef === void 0 ? void 0 : scopeRootRef.current) || undefined); const index = allInputs.findIndex(el => el === input); const prev = index > 0 ? allInputs[index - 1] : undefined; const next = index >= 0 ? allInputs[index + 1] : undefined; if (key === 'Backspace') { if (typedLen === 0 && prev) { event.preventDefault(); focusInput(prev, 'end'); } return; } if (key === 'ArrowRight') { if (hasSelection) { try { input.setSelectionRange(selEnd, selEnd); } catch {} event.preventDefault(); return; } if (atEnd && next) { event.preventDefault(); focusInput(next, 'start'); } return; } if (key === 'ArrowLeft') { if (hasSelection) { try { input.setSelectionRange(selStart, selStart); } catch {} event.preventDefault(); return; } if (atStart && prev) { event.preventDefault(); focusInput(prev, 'end'); } return; } const allowMask = () => { if (!keysToHandle) { return true; } const reg = getKeysToHandle({ keysToHandle, input }); return reg ? reg.test(key) : true; }; if (key.length === 1 && allowMask()) { if (!hasSelection && atEnd && typedLen >= size && next) { var _options$onTransferTo; event.preventDefault(); options === null || options === void 0 || (_options$onTransferTo = options.onTransferToNext) === null || _options$onTransferTo === void 0 || _options$onTransferTo.call(options, { key, currentInput: input, nextInput: next }); focusInput(next, 'start'); return; } } }, [keysToHandle, options, scopeRootRef]); const onInput = useCallback(event => { var _input$selectionStart2, _input$selectionEnd2; const input = event.currentTarget; if (document.activeElement !== input) { return; } const size = getInputVisualSize(input); const selStart = (_input$selectionStart2 = input.selectionStart) !== null && _input$selectionStart2 !== void 0 ? _input$selectionStart2 : 0; const selEnd = (_input$selectionEnd2 = input.selectionEnd) !== null && _input$selectionEnd2 !== void 0 ? _input$selectionEnd2 : selStart; const atEnd = selStart === size && selEnd === size; if (!atEnd) { return; } const typedLen = getTypedLengthBasic(input.value || '', input.placeholder || '', size); if (typedLen < size) { return; } const next = getAdjacentInput((scopeRootRef === null || scopeRootRef === void 0 ? void 0 : scopeRootRef.current) || undefined, input, 'next'); if (next) { deferFocus(() => { focusInput(next, 'start'); }); } }, [scopeRootRef]); return { onKeyDown, onInput }; } function listAllInputs(scope) { try { const root = scope || document; return Array.from(root.querySelectorAll('.dnb-multi-input-mask__input')); } catch { return []; } } function getAdjacentInput(scope, input, direction) { const allInputs = listAllInputs(scope); const index = allInputs.findIndex(el => el === input); if (index < 0) { return undefined; } if (direction === 'prev') { return index > 0 ? allInputs[index - 1] : undefined; } return index < allInputs.length - 1 ? allInputs[index + 1] : undefined; } function getTypedLengthBasic(value, placeholder, size) { if (!size) { return value.length; } const n = Math.min(size, value.length); let count = 0; for (let i = 0; i < n; i++) { if (!placeholder || placeholder[i] !== value[i]) { count++; } } return count; } 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 === undefined || selection === null) { return undefined; } const maskIndex = selection === input.size ? masks.length - 1 : selection; return masks[maskIndex]; } function focusInput(el, _where) { try { el.focus(); } catch {} } function deferFocus(cb) { if (typeof queueMicrotask === 'function') { queueMicrotask(cb); return; } Promise.resolve().then(cb); } function getInputVisualSize(input) { if (typeof input.size === 'number' && input.size > 0) { return input.size; } if (typeof input.maxLength === 'number' && input.maxLength > 0) { return input.maxLength; } return input.value ? input.value.length : 0; } export default useHandleCursorPosition; //# sourceMappingURL=useHandleCursorPosition.js.map