@@ -74,7 +74,7 @@ css_class_enum! {
7474#[ function_component( Input ) ]
7575pub fn input < T , E > ( props : & InputProps < T , E > ) -> Html
7676where
77- T : Display + Clone + PartialEq ,
77+ T : Display + Clone + PartialEq + ' static ,
7878 E : Display + Clone + PartialEq ,
7979{
8080 let success = props. parsed . as_ref ( ) . map ( |x| x. is_ok ( ) ) . unwrap_or ( false ) ;
@@ -85,26 +85,41 @@ where
8585 // so the noderef becomes valid.
8686 let first_render = use_state ( || true ) ;
8787 let trigger = use_force_update ( ) ;
88- let applied_default_value = use_state ( || false ) ;
8988 let node_ref = use_node_ref ( ) ;
9089
9190 if * first_render {
9291 first_render. set ( false ) ;
9392 trigger. force_update ( ) ;
9493 }
9594
96- if let ( false , Some ( input_element) ) =
97- ( * applied_default_value, node_ref. cast :: < HtmlInputElement > ( ) )
98- {
99- if let Some ( d) = props. default . as_ref ( ) {
100- input_element. set_value ( & d. to_string ( ) ) ;
95+ let user_edited = use_state ( || false ) ;
96+ let last_default_value = use_state ( || None ) ;
97+ if let Some ( input_element) = node_ref. cast :: < HtmlInputElement > ( ) {
98+ // Re-apply default if it changes
99+ if !* user_edited && props. default != * last_default_value {
100+ if let Some ( d) = props. default . as_ref ( ) {
101+ input_element. set_value ( & d. to_string ( ) ) ;
102+ } else {
103+ input_element. set_value ( "" ) ;
104+ }
105+ let mut init = InputEventInit :: new ( ) ;
106+ init. data ( Some ( "ignore" ) ) ;
101107 input_element
102- . dispatch_event ( & InputEvent :: new ( "input" ) . unwrap ( ) )
108+ . dispatch_event ( & InputEvent :: new_with_event_init_dict ( "input" , & init ) . unwrap ( ) )
103109 . unwrap ( ) ;
110+ last_default_value. set ( props. default . clone ( ) ) ;
104111 }
105- applied_default_value. set ( true ) ;
106112 }
107113
114+ let prop_oninput = props. oninput . clone ( ) ;
115+ // Wrap callback to determine when user performed an edit
116+ let oninput = Callback :: from ( move |event : InputEvent | {
117+ if !event. data ( ) . map_or ( false , |d| d == "ignore" ) {
118+ user_edited. set ( true ) ;
119+ }
120+ prop_oninput. emit ( event) ;
121+ } ) ;
122+
108123 html ! {
109124 <>
110125 <label class="form-label" for ={ id. clone( ) } >
@@ -113,7 +128,7 @@ where
113128 <div class={ classes!( if props. button. is_some( ) { Some ( "input-group" ) } else { None } ) } >
114129 <div class={ classes!( if props. button. is_some( ) { Some ( "input-group" ) } else { None } , if success || error { Some ( "has-icon-right" ) } else { None } ) } >
115130 <input id={ id} class="form-input" type ={ props. r#type. to_string( ) } ref={ node_ref. clone( ) }
116- oninput={ props . oninput. clone ( ) } placeholder={ props. placeholder. as_ref( ) . map( ToString :: to_string) }
131+ oninput={ oninput} placeholder={ props. placeholder. as_ref( ) . map( ToString :: to_string) }
117132 />
118133 {
119134 if let Some ( parsed) = props. parsed. as_ref( ) {
@@ -359,6 +374,7 @@ where
359374 let user_edited = use_state ( || false ) ;
360375 let last_default_value = use_state ( || None ) ;
361376 if let Some ( input_element) = node_ref. cast :: < HtmlInputElement > ( ) {
377+ // Re-apply default if it changes
362378 if !* user_edited && props. default != * last_default_value {
363379 if let Some ( d) = props. default . as_ref ( ) {
364380 input_element. set_value ( d) ;
@@ -375,11 +391,12 @@ where
375391 }
376392
377393 let prop_oninput = props. oninput . clone ( ) ;
394+ // Wrap callback to determine when user performed an edit
378395 let oninput = Callback :: from ( move |event : InputEvent | {
379396 if !event. data ( ) . map_or ( false , |d| d == "ignore" ) {
380- prop_oninput. emit ( event) ;
381397 user_edited. set ( true ) ;
382398 }
399+ prop_oninput. emit ( event) ;
383400 } ) ;
384401
385402 html ! {
0 commit comments