Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/wojtekmaj/predict-input-value. Predicts the input value during KeyDown or KeyPress events, before the input is actually changed
Something went wrong. Try again.
2.0 kB · 77 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778const excludeList = [ 'Alt', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'Enter', 'Escape', 'Shift', 'Tab',];
/** * Predicts what the value will be after the next keyup given keydown event. * * @param {KeyboardEvent} event Keydown event * @returns {string} Predicted input value */export default function predictInputValue(event: KeyboardEvent): string | null { // Support only keydown and keypress event if (event.type !== 'keydown' && event.type !== 'keypress') { return null; }
// Skip Cmd+A and other key combinations if (event.metaKey) { return null; }
if (excludeList.includes(event.key)) { return null; }
const { target: element } = event;
// Only support input and textarea elements if (!(element instanceof HTMLInputElement) && !(element instanceof HTMLTextAreaElement)) { return null; }
// We can’t predict values in number inputs if (element.type === 'number') { return null; }
let { selectionStart } = element; const { selectionEnd } = element;
if (selectionStart === null || selectionEnd === null) { return null; }
const nextValueArr = element.value.split(''); let { key: replaceWith } = event;
if (event.key === 'Backspace') { if (selectionStart && selectionStart === selectionEnd) { /** * There’s no text selected, so pressing backspace will remove the character before the caret. * That’s equal to one character before the caret being selected when Backspace is pressed. */ selectionStart -= 1; } replaceWith = ''; }
/** * If we’re going to add another character, check if we’re not going over the limit set by * maxLength. If so, entering the next character will fail, and thus, nextValue will be equal to * value. */ if (!replaceWith || element.maxLength < 0 || nextValueArr.length < element.maxLength) { nextValueArr.splice(selectionStart, selectionEnd - selectionStart, replaceWith); }
return nextValueArr.join('');}