reagent-project / reagent

A minimalistic ClojureScript interface to React.js
http://reagent-project.github.io/
MIT License
4.75k stars 414 forks source link

Controlled input loses cursor with React 18 when input type is :email or :number #609

Open flyingmachine opened 1 week ago

flyingmachine commented 1 week ago

Inputs of type :email and :number exhibit the controlled-input cursor bug: as you type, the cursor will always reappear at the end end of the input. Inputs of type :text and :password don't exhibit this behavior.

Little repo to repro: https://github.com/flyingmachine/reagent-react-18-controlled-input

(ns main.app
  (:require
   ["react" :as react]
   ["react-dom/client" :refer [createRoot]]
   [goog.dom :as gdom]
   [reagent.core :as r]
   [reagent.dom.client :as client]))

(defonce root (createRoot  (gdom/getElement "app")))

(defn text []
  (r/with-let [text (r/atom "")]
    [:input {:type :text
             :on-change #(reset! text (.. % -target -value))
             :value @text}]))

(defn email []
  (r/with-let [text (r/atom "")]
    [:input {:type :email
             :on-change #(reset! text (.. % -target -value))
             :value @text}]))

(defn number []
  (r/with-let [text (r/atom "")]
    [:input {:type :number
             :on-change #(reset! text (.. % -target -value))
             :value @text}]))

(defn app
  []
  [:table
   [:tbody
    [:tr [:td "text"] [:td [text]]]
    [:tr [:td "email"] [:td [email]]]
    [:tr [:td "number"] [:td [number]]]]])

(defn ^:dev/after-load start []
  (client/render root [app]))

(defn init
  []
  (start))
mike-thompson-day8 commented 1 week ago

I originally implemented this solution for input fields: https://github.com/reagent-project/reagent/blob/886d2035518a77cb7f1ecf713256fd0fee89bd72/src/reagent/impl/input.cljs#L34-L74

But it relies on selection API being present on the input: https://github.com/reagent-project/reagent/blob/886d2035518a77cb7f1ecf713256fd0fee89bd72/src/reagent/impl/input.cljs#L9-L10

I think email can easily be added to that list because these days it supports the necessary API. (Maybe it always did).

But it doesn't appear as if number can be added - so that would have to be solved another way, probably with much more effort.

Deraen commented 1 week ago

Fixing for email type seems simple enough.

Related: https://github.com/reagent-project/reagent/issues/504 Removing the rAF scheduling would remove the need for input workaround, but it would also be a big breaking change in Reagent so not sure if it going to happen ever. You could use UIx/Helix instead.