Maintain cur pos when updating React inputs

I’m trying to create an input that adds thousand separators to characters entered by users. Additionally, I would like to enable the functionality of deleting characters when the cursor is placed directly before or after a thousand separator by pressing the delete or backspace key respectively. Is there a concise way of creating an input with these features in React?

My code is as follows:

import React, { useState, useRef } from 'react';

const NumericInput = () => {
  const [value, setValue] = useState('');
  const inputRef = useRef(null);

const onKeyDown = (e) => {
  const inputElement = inputRef.current;
  const caretStart = inputElement.selectionStart;
  const caretEnd = inputElement.selectionEnd;

  if (e.key === 'Backspace' && caretStart === caretEnd && caretStart > 0) {
    const previousChar = inputElement.value.charAt(caretStart - 1);
    if (previousChar === ',' || previousChar === ' ') {
      e.preventDefault();
      inputElement.setSelectionRange(caretStart - 1, caretEnd - 1);
      return;
    }
  }

  if (e.key === 'Delete' && caretStart === caretEnd && caretEnd < inputElement.value.length) {
    const nextChar = inputElement.value.charAt(caretStart);
    if (nextChar === ',' || nextChar === ' ') {
      e.preventDefault();
      inputElement.setSelectionRange(caretStart + 1, caretEnd + 1);
      return;
    }
  }

  if (!/^-?\d*$/g.test(value) && e.key !== '-' && e.key !== 'Backspace') {
    e.preventDefault();
  }
};

  const onChange = (e) => {
    const inputValue = e.target.value.replace(/[^0-9-]/g, '');
    setValue(inputValue);

    const inputElement = inputRef.current;
    const caretPosition = Math.max(0, inputElement.selectionStart + (formatValue(inputValue).match(/,/g) || []).length - (formatValue(value).match(/,/g) || []).length);
    inputElement.value = formatValue(inputValue);
    inputElement.setSelectionRange(caretPosition, caretPosition);
  };

  const formatValue = (value) => (value ? value.replace(/\B(?=(\d{3})+(?!\d))/g, ',') : '');

  return (
      <input
        ref={inputRef}
        placeholder='Type Number'
        type='text'
        onKeyDown={onKeyDown}
        onChange={onChange}
        value={formatValue(value)}
      />
  );
};

export default NumericInput;

I need help modifying my code to enable the ability to delete characters when the cursor is placed directly before or after a thousand separator by pressing the delete or backspace key respectively. Is there a concise way of creating an input with these features in React?

To enable the ability to delete characters when the cursor is placed directly before or after a thousand separator by pressing the delete or backspace key respectively, you can modify the onKeyDown function in your code as follows:

const onKeyDown = (e) => {
  const inputElement = inputRef.current;
  const caretStart = inputElement.selectionStart;
  const caretEnd = inputElement.selectionEnd;
  const valueWithoutSeparators = value.replace(/[, ]/g, '');

  if (e.key === 'Backspace' && caretStart === caretEnd && caretStart > 0) {
    const previousChar = inputElement.value.charAt(caretStart - 1);
    if (previousChar === ',' || previousChar === ' ') {
      e.preventDefault();
      inputElement.setSelectionRange(caretStart - 1, caretEnd - 1);
      return;
    }
  }

  if (e.key === 'Delete' && caretStart === caretEnd && caretEnd < inputElement.value.length) {
    const nextChar = inputElement.value.charAt(caretStart);
    if (nextChar === ',' || nextChar === ' ') {
      e.preventDefault();
      inputElement.setSelectionRange(caretStart + 1, caretEnd + 1);
      return;
    }
  }

  if (!/^[-\d\s]+$/.test(valueWithoutSeparators) && e.key !== '-' && e.key !== 'Backspace') {
    e.preventDefault();
  }
};

This modified code checks for the presence of separators (, and ) before allowing the delete or backspace key to function as expected. It also updates the regular expression used to validate the input value.

With these modifications, your NumericInput component will have the ability to delete characters when the cursor is placed directly before or after a thousand separator by pressing the delete or backspace key respectively.