title: how to handle undo/redo in programmatically modified inputs with react?
body: <p>Trying to implement a text input with a select that inserts options into the input (at the cursor position), I have noticed that the undo/redo behaviour is inconsistent with the browsers I tried (chrome v94, firefox 89, safari 14, edge v93)</p>
  <p>Below is a sample code example where you can notice the difference of behaviour between two inputs, one where the value is set as is, and one where the value is transformed to uppercase</p>
  <p><code>ctrl/cmd + z</code> works to undo and <code>ctrl/cmd + shift + z</code> works to redo only in the first input</p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="false" data-babel="true">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>const { useState } = React;
  
  const Example = () =&gt; {
    const [text, setText] = useState("");
    const [upperCaseText, setUpperCaseText] = useState("");
  
    return (
      &lt;div className="App"&gt;
        &lt;input
          type="text"
          value={text}
          onChange={({ target }) =&gt; setText(target.value)}
          placeholder="text set as is"
        /&gt;
        &lt;input
          type="text"
          value={upperCaseText}
          onChange={({ target }) =&gt; setUpperCaseText(target.value.toUpperCase())}
          placeholder="text uppercased"
        /&gt;
      &lt;/div&gt;
      )
  };
  
  
  ReactDOM.render(
    &lt;Example /&gt;,
    document.body
  );</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"&gt;&lt;/script&gt;
  &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"&gt;&lt;/script&gt;</code></pre>
  </div>
  </div>
  </p>
  <p>There is one similar post <a href="https://stackoverflow.com/a/41274320/5599091">and answer here</a> but it only works with limitations, <code>document.execCommand</code> <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand" rel="nofollow noreferrer">is deprecated</a>, and not supported on firefox.
  I have also tried to dispatch an event and force the input value as <a href="https://stackoverflow.com/a/46012210/5599091">described here</a> and even dispatch <code>keydown</code> events, but although the input field is populated, the browsers still don't recognize those inputs as user inputs and exclude them from the input undo/redo history.</p>
  <p>Is there a way to have browsers treat programmatic changes to the input the same way as manual user input (keypress or clipboard paste), or does one have to implement a custom input change history here?</p>