Feat: massive changes to definition of components
This change switches back to the original `ctx<props>` syntax for commponents. This lets lifetime elision to remove the need to match exactly which lifetime (props or ctx) gets carried to the output. As such, `Props` is currently required to be static. It *is* possible to loosen this restriction, and will be done in the future, though only through adding metadata about the props through the Props derive macro. Implementing the IS_STATIC trait is unsafe, so the derive macro will do it through some heuristics. For now, this unlocks sharing vnodes from parents to children, enabling pass-thru components, fragments, portals, etc.
This commit is contained in:
1 parent
c1fd848f89
commit
508c560320
82 files changed
+692
-558
No files matched your search
@@ -2,7 +2,7 @@ fn main() {}
|
||||
|
||||
use dioxus_core::prelude::*;
|
||||
|
||||
static Example: FC<()> = |ctx, props| {
|
||||
static Example: FC<()> = |ctx| {
|
||||
ctx.render(dioxus_core::prelude::LazyNodes::new(move |ctx| {
|
||||
let bump = ctx.bump();
|
||||
dioxus::builder::ElementBuilder::new(ctx, "h1")
|
||||
@@ -15,3 +15,16 @@ static Example: FC<()> = |ctx, props| {
|
||||
.finish()
|
||||
}))
|
||||
};
|
||||
|
||||
struct Props {
|
||||
text: String,
|
||||
}
|
||||
static Example2: FC<Props> = |ctx| {
|
||||
ctx.render(dioxus_core::prelude::LazyNodes::new(move |__ctx| {
|
||||
let bump = __ctx.bump();
|
||||
dioxus::builder::ElementBuilder::new(__ctx, "h1")
|
||||
.children([{ dioxus::builder::text3(bump, format_args!("{}", ctx.text)) }])
|
||||
// .children([{ dioxus::builder::text3(bump, format_args!("hello")) }])
|
||||
.finish()
|
||||
}))
|
||||
};
|
||||
@@ -21,12 +21,12 @@ struct ListItem {
|
||||
age: u32,
|
||||
}
|
||||
|
||||
fn app<'a>(ctx: Context<'a>, props: &Props) -> DomTree {
|
||||
fn app(ctx: Context<Props>) -> VNode {
|
||||
let (val, set_val) = use_state(&ctx, || 0);
|
||||
|
||||
ctx.render(dioxus::prelude::LazyNodes::new(move |c| {
|
||||
let mut root = builder::ElementBuilder::new(c, "div");
|
||||
for child in &props.items {
|
||||
for child in &ctx.items {
|
||||
// notice that the child directly borrows from our vec
|
||||
// this makes lists very fast (simply views reusing lifetimes)
|
||||
// <ChildItem item=child hanldler=setter />
|
||||
@@ -55,11 +55,11 @@ struct ChildProps {
|
||||
item_handler: Callback<i32>,
|
||||
}
|
||||
|
||||
fn ChildItem<'a>(ctx: Context<'a>, props: &ChildProps) -> DomTree {
|
||||
fn ChildItem<'a>(ctx: Context<ChildProps>) -> VNode {
|
||||
ctx.render(rsx! {
|
||||
div {
|
||||
onclick: move |evt| (props.item_handler)(10)
|
||||
h1 { "abcd123" }
|
||||
// onclick: move |evt| (ctx.item_handler)(10)
|
||||
h1 { "abcd123 {ctx.item.name}" }
|
||||
h2 { "abcd123" }
|
||||
div {
|
||||
"abcd123"
|
||||
|
||||
@@ -16,7 +16,7 @@ fn main() {
|
||||
};
|
||||
}
|
||||
|
||||
static Example: FC<()> = |ctx, props| {
|
||||
static Example: FC<()> = |ctx| {
|
||||
let nodes = ctx.children();
|
||||
|
||||
//
|
||||
@@ -26,43 +26,3 @@ static Example: FC<()> = |ctx, props| {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct MyContext<'a, T> {
|
||||
props: &'a T,
|
||||
inner: &'a Scope,
|
||||
}
|
||||
impl<'a, T> MyContext<'a, T> {
|
||||
fn children(&self) -> Vec<VNode<'a>> {
|
||||
todo!()
|
||||
}
|
||||
pub fn render2<F: for<'b> FnOnce(&'b NodeCtx<'a>) -> VNode<'a> + 'a>(
|
||||
&self,
|
||||
lazy_nodes: LazyNodes<'a, F>,
|
||||
) -> VNode<'a> {
|
||||
self.inner.render2(lazy_nodes)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Deref for MyContext<'a, T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.props
|
||||
}
|
||||
}
|
||||
|
||||
struct MyProps {
|
||||
title: String,
|
||||
}
|
||||
|
||||
fn example(scope: MyContext<MyProps>) -> VNode {
|
||||
let childs = scope.children();
|
||||
|
||||
scope.inner.render2(rsx! {
|
||||
div {
|
||||
"{scope.title}"
|
||||
{childs}
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -10,19 +10,20 @@ struct Props {
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
static Example: FC<Props> = |ctx, props| {
|
||||
static Example: FC<Props> = |cpt| {
|
||||
todo!()
|
||||
|
||||
// let value = ctx.use_context(|c: &SomeContext| c.items.last().unwrap());
|
||||
|
||||
// ctx.render(LazyNodes::new(move |bump| {
|
||||
// builder::ElementBuilder::new(bump, "button")
|
||||
// .on("click", move |_| {
|
||||
// println!("Value is {}", props.name);
|
||||
// println!("Value is {}", ctx.name);
|
||||
// println!("Value is {}", value.as_str());
|
||||
// println!("Value is {}", *value);
|
||||
// })
|
||||
// .on("click", move |_| {
|
||||
// println!("Value is {}", props.name);
|
||||
// println!("Value is {}", ctx.name);
|
||||
// })
|
||||
// .finish()
|
||||
// }))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use dioxus_core::component::fc_to_builder;
|
||||
use dioxus_core::prelude::*;
|
||||
|
||||
static BLAH: FC<()> = |ctx, _props| {
|
||||
static BLAH: FC<()> = |ctx| {
|
||||
let g = "asd".to_string();
|
||||
ctx.render(rsx! {
|
||||
div {
|
||||
@@ -17,7 +17,7 @@ pub struct ExampleProps {
|
||||
some_field: String,
|
||||
}
|
||||
|
||||
static SomeComponent: FC<ExampleProps> = |ctx, _props| {
|
||||
static SomeComponent: FC<ExampleProps> = |ctx| {
|
||||
let blah = rsx! {
|
||||
div {}
|
||||
};
|
||||
|
||||
@@ -10,14 +10,21 @@ fn main() {
|
||||
.map(|f| f / 3);
|
||||
}
|
||||
|
||||
static Example: FC<()> = |ctx, props| {
|
||||
static Example: FC<()> = |ctx| {
|
||||
let (name, set_name) = use_state(&ctx, || "...?");
|
||||
|
||||
ctx.render(html! {
|
||||
<div>
|
||||
<h1> "Hello, {name}" </h1>
|
||||
<button onclick={move |_| set_name("jack")}> "jack!" </button>
|
||||
<button onclick={move |_| set_name("jill")}> "jill!" </button>
|
||||
</div>
|
||||
})
|
||||
ctx.render(rsx!(
|
||||
div {
|
||||
h1 { "Hello, {name}" }
|
||||
// look ma - we can rsx! and html! together
|
||||
{["jack", "jill"].iter().map(|f| html!(<button onclick={move |_| set_name(f)}> "{f}" </button>))}
|
||||
}
|
||||
))
|
||||
};
|
||||
|
||||
pub fn render<'src, 'a, F: for<'b> FnOnce(&'b NodeCtx<'src>) -> VNode<'src> + 'src + 'a, P>(
|
||||
ctx: &'a Context<'src, P>,
|
||||
lazy_nodes: LazyNodes<'src, F>,
|
||||
) -> VNode<'src> {
|
||||
ctx.render(lazy_nodes)
|
||||
}
|
||||
@@ -43,7 +43,7 @@ mod baller {
|
||||
use super::*;
|
||||
pub struct BallerProps {}
|
||||
|
||||
pub fn Baller(ctx: Context, props: &()) -> DomTree {
|
||||
pub fn Baller(ctx: Context<()>) -> VNode {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,7 @@ pub struct TallerProps {
|
||||
a: &'static str,
|
||||
}
|
||||
|
||||
pub fn Taller(ctx: Context, props: &TallerProps) -> DomTree {
|
||||
pub fn Taller(ctx: Context<TallerProps>) -> VNode {
|
||||
let b = true;
|
||||
todo!()
|
||||
}
|
||||
@@ -90,7 +90,7 @@ fn main() {}
|
||||
// div(bump)
|
||||
// .attr("class", "edit")
|
||||
// .child(text("Hello"))
|
||||
// .child(text(ctx.props.text.as_ref()))
|
||||
// .child(text(ctx.ctx.text.as_ref()))
|
||||
// .finish()
|
||||
// })
|
||||
// }
|
||||
@@ -123,7 +123,7 @@ fn main() {}
|
||||
// _ => html! { <div> </div> },
|
||||
// };
|
||||
|
||||
// if ctx.props.blah {
|
||||
// if ctx.ctx.blah {
|
||||
// html! { <div> </div> }
|
||||
// } else {
|
||||
// tex
|
||||
|
||||
@@ -7,23 +7,19 @@ use dioxus_core::prelude::*;
|
||||
|
||||
fn main() {}
|
||||
|
||||
static Header: FC<()> = |ctx, props| {
|
||||
let inner = use_ref(&ctx, || 0);
|
||||
static Header: FC<()> = |ctx| {
|
||||
let inner = use_ref(ctx, || 0);
|
||||
|
||||
let handler1 = move || println!("Value is {}", inner.borrow());
|
||||
|
||||
ctx.render(dioxus::prelude::LazyNodes::new(|nodectx| {
|
||||
builder::ElementBuilder::new(nodectx, "div")
|
||||
.child(VNode::Component(VComponent::new(
|
||||
Bottom,
|
||||
nodectx.bump().alloc(()),
|
||||
None,
|
||||
)))
|
||||
.child(VNode::Component(VComponent::new(Bottom, (), None)))
|
||||
.finish()
|
||||
}))
|
||||
};
|
||||
|
||||
static Bottom: FC<()> = |ctx, props| {
|
||||
static Bottom: FC<()> = |ctx| {
|
||||
ctx.render(html! {
|
||||
<div>
|
||||
<h1> "bruh 1" </h1>
|
||||
@@ -32,7 +28,7 @@ static Bottom: FC<()> = |ctx, props| {
|
||||
})
|
||||
};
|
||||
|
||||
fn Top(ctx: Context, a: &str, b: &i32, c: &impl Fn()) -> DomTree {
|
||||
fn Top(ctx: Context<()>) -> VNode {
|
||||
ctx.render(html! {
|
||||
<div>
|
||||
<h1> "bruh 1" </h1>
|
||||
@@ -124,44 +120,44 @@ fn try_test() {
|
||||
// test_poc()
|
||||
}
|
||||
|
||||
fn test_poc(ctx: Context) {
|
||||
let b = Bump::new();
|
||||
// fn test_poc(ctx: Context) {
|
||||
// let b = Bump::new();
|
||||
|
||||
let h = Args {
|
||||
a: CuOpt::Some("ASD"),
|
||||
b: CuOpt::Some(123),
|
||||
c: CuOpt::Some(|| {}),
|
||||
// c: CuOpt::Some(b.alloc(|| {})),
|
||||
// c: CuOpt::Some(Box::new(|| {}) as Box<dyn Fn()>),
|
||||
};
|
||||
// let h = Args {
|
||||
// a: CuOpt::Some("ASD"),
|
||||
// b: CuOpt::Some(123),
|
||||
// c: CuOpt::Some(|| {}),
|
||||
// // c: CuOpt::Some(b.alloc(|| {})),
|
||||
// // c: CuOpt::Some(Box::new(|| {}) as Box<dyn Fn()>),
|
||||
// };
|
||||
|
||||
let h2 = Args {
|
||||
a: CuOpt::Some("ASD"),
|
||||
b: CuOpt::Some(123),
|
||||
c: CuOpt::Some(|| {}),
|
||||
// c: CuOpt::Some(b.alloc(|| {})),
|
||||
// c: CuOpt::Some(Box::new(|| {}) as Box<dyn Fn()>),
|
||||
// c: CuOpt::Some(Box::new(|| {}) as Box<dyn Fn()>),
|
||||
// c: CuOpt::Some(Box::new(|| {}) as Box<dyn Fn()>),
|
||||
};
|
||||
// let h2 = Args {
|
||||
// a: CuOpt::Some("ASD"),
|
||||
// b: CuOpt::Some(123),
|
||||
// c: CuOpt::Some(|| {}),
|
||||
// // c: CuOpt::Some(b.alloc(|| {})),
|
||||
// // c: CuOpt::Some(Box::new(|| {}) as Box<dyn Fn()>),
|
||||
// // c: CuOpt::Some(Box::new(|| {}) as Box<dyn Fn()>),
|
||||
// // c: CuOpt::Some(Box::new(|| {}) as Box<dyn Fn()>),
|
||||
// };
|
||||
|
||||
// dbg!((&h.a).memo((&&h2.a)));
|
||||
// dbg!((&h.b).memo((&&h2.b)));
|
||||
// dbg!((&h.c).memo((&&h2.c)));
|
||||
//
|
||||
// ctx: Context
|
||||
Top(ctx, &h.a.unwrap(), &h.b.unwrap(), &h.c.unwrap());
|
||||
}
|
||||
// // dbg!((&h.a).memo((&&h2.a)));
|
||||
// // dbg!((&h.b).memo((&&h2.b)));
|
||||
// // dbg!((&h.c).memo((&&h2.c)));
|
||||
// //
|
||||
// // ctx: Context
|
||||
// Top(ctx, &h.a.unwrap(), &h.b.unwrap(), &h.c.unwrap());
|
||||
// }
|
||||
|
||||
fn test_realzies() {
|
||||
let h = Args {
|
||||
a: CuOpt::Some("ASD"),
|
||||
b: CuOpt::Some(123),
|
||||
c: CuOpt::Some(|| {}),
|
||||
};
|
||||
// fn test_realzies() {
|
||||
// let h = Args {
|
||||
// a: CuOpt::Some("ASD"),
|
||||
// b: CuOpt::Some(123),
|
||||
// c: CuOpt::Some(|| {}),
|
||||
// };
|
||||
|
||||
let g = |ctx: Context| {
|
||||
//
|
||||
Top(ctx, &h.a.unwrap(), &h.b.unwrap(), &h.c.unwrap())
|
||||
};
|
||||
}
|
||||
// let g = |ctx: Context| {
|
||||
// //
|
||||
// Top(ctx, &h.a.unwrap(), &h.b.unwrap(), &h.c.unwrap())
|
||||
// };
|
||||
// }
|
||||
@@ -16,22 +16,22 @@ fn test() {
|
||||
// let g: FC<ButtonProps> = CustomButton;
|
||||
}
|
||||
|
||||
trait Render {
|
||||
fn render(ctx: Context, props: &Self) -> DomTree;
|
||||
trait Render: Sized {
|
||||
fn render(ctx: Context<Self>) -> VNode;
|
||||
}
|
||||
// include as much as you might accept
|
||||
struct Button<'a> {
|
||||
onhover: Option<&'a dyn Fn()>,
|
||||
struct Button {
|
||||
onhover: Option<Box<dyn Fn()>>,
|
||||
}
|
||||
|
||||
impl Render for Button<'_> {
|
||||
fn render(ctx: Context, _props: &Self) -> DomTree {
|
||||
impl Render for Button {
|
||||
fn render(ctx: Context<Self>) -> VNode {
|
||||
let _onfocus = move |_evt: ()| log::debug!("Focused");
|
||||
|
||||
// todo!()
|
||||
ctx.render(rsx! {
|
||||
button {
|
||||
// ..props.attrs,
|
||||
// ..ctx.attrs,
|
||||
class: "abc123",
|
||||
// style: { a: 2, b: 3, c: 4 },
|
||||
onclick: move |_evt| {
|
||||
@@ -47,7 +47,7 @@ impl Render for Button<'_> {
|
||||
}
|
||||
|
||||
// #[fc]
|
||||
// fn Button(ctx: Context, onhover: Option<&dyn Fn()>) -> DomTree {}
|
||||
// fn Button(ctx: Context, onhover: Option<&dyn Fn()>) -> VNode {}
|
||||
|
||||
// h1 {
|
||||
// tag: "type", abc: 123, class: "big small wide short",
|
||||
|
||||
@@ -14,10 +14,28 @@ struct SomeProps {
|
||||
name: String,
|
||||
}
|
||||
|
||||
static Example: FC<SomeProps> = |ctx, _props| {
|
||||
static Example: FC<SomeProps> = |ctx| {
|
||||
ctx.render(html! {
|
||||
<div>
|
||||
<h1> "hello world!" </h1>
|
||||
</div>
|
||||
})
|
||||
};
|
||||
|
||||
// #[test]
|
||||
#[derive(PartialEq, Clone)]
|
||||
struct MyStruct {
|
||||
a: String,
|
||||
}
|
||||
|
||||
fn check_before_to_owned() {
|
||||
let new_str = MyStruct {
|
||||
a: "asd".to_string(),
|
||||
};
|
||||
|
||||
let out = town(&new_str);
|
||||
}
|
||||
|
||||
fn town<T: ToOwned + PartialEq>(t: &T) -> T::Owned {
|
||||
t.to_owned()
|
||||
}
|
||||
Reference in new issue
Block a user