فهرست منبع

Use SuperInto and correct Owner for props defaults (#3959)

pandarrr 1 ماه پیش
والد
کامیت
0c0f0e96df
2فایلهای تغییر یافته به همراه50 افزوده شده و 1 حذف شده
  1. 8 1
      packages/core-macro/src/props/mod.rs
  2. 42 0
      packages/core-macro/tests/rsx.rs

+ 8 - 1
packages/core-macro/src/props/mod.rs

@@ -1416,10 +1416,15 @@ Finally, call `.build()` to create the instance of `{name}`.
                     // If field has `into`, apply it to the default value.
                     // Ignore any blank defaults as it causes type inference errors.
                     let is_default = *default == parse_quote!(::core::default::Default::default());
+                    // If this is a signal type, we use super_into and the props struct as the owner
+                    let is_child_owned_type = child_owned_type(field.ty);
+
                     let mut into = quote!{};
 
                     if !is_default {
-                        if field.builder_attr.auto_into {
+                        if is_child_owned_type {
+                            into = quote!{ .super_into() }
+                        } else if field.builder_attr.auto_into {
                             into = quote!{ .into() }
                         } else if field.builder_attr.auto_to_string {
                             into = quote!{ .to_string() }
@@ -1428,6 +1433,8 @@ Finally, call `.build()` to create the instance of `{name}`.
 
                     if field.builder_attr.skip {
                         quote!(let #name = #default #into;)
+                    } else if is_child_owned_type {
+                        quote!(let #name = #helper_trait_name::into_value(#name, || with_owner(self.owner.clone(), move || (#default) #into));)
                     } else {
                         quote!(let #name = #helper_trait_name::into_value(#name, || #default #into);)
                     }

+ 42 - 0
packages/core-macro/tests/rsx.rs

@@ -49,8 +49,50 @@ mod test_default_into {
         pub some_data: bool,
 
         pub some_other_data: bool,
+
+        // Test default values for signals
+        #[props(default)]
+        read_only_w_default: ReadOnlySignal<bool>,
+
+        #[props(default = true)]
+        read_only_w_default_val: ReadOnlySignal<bool>,
+
+        #[props(default = ReadOnlySignal::new(Signal::new(true)))]
+        read_only_w_default_val_explicit: ReadOnlySignal<bool>,
+
+        // Test default values for callbacks/event handlers
+        #[props(default)]
+        callback_w_default: Callback,
+
+        #[props(default = move |_| {})]
+        callback_w_default_val_closure: Callback,
+
+        #[props(default = {
+            fn test(_: ()) {}
+            test
+        })]
+        callback_w_default_val_expr_fn: Callback,
+
+        #[props(default = Callback::new(move |_: ()| {}))]
+        callback_w_default_val_explicit: Callback,
+
+        #[props(default)]
+        event_handler_w_default: EventHandler<KeyboardEvent>,
+
+        #[props(default = move |_| {})]
+        event_handler_w_default_val_closure: EventHandler<KeyboardEvent>,
+
+        #[props(default = {
+            fn test(_: KeyboardEvent) {}
+            test
+        })]
+        event_handler_w_default_val_expr_fn: EventHandler<KeyboardEvent>,
+
+        #[props(default = EventHandler::new(move |_: KeyboardEvent| {}))]
+        event_handler_w_default_val_explicit: EventHandler<KeyboardEvent>,
     }
 }
+
 /// This test ensures that read-only signals that contain an option (`Signal<Option<u16>>`)
 /// are correctly created as default when not provided.
 ///