mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-09-20 14:21:58 +00:00
wip: move children onto scope
This commit is contained in:
parent
d1b294fff0
commit
f438bbcfd2
6 changed files with 85 additions and 19 deletions
|
@ -37,7 +37,7 @@ once_cell = "1.8.0"
|
||||||
|
|
||||||
indexmap = "1.7.0"
|
indexmap = "1.7.0"
|
||||||
|
|
||||||
# # Serialize the Edits for use in Webview/Liveview instances
|
# Serialize the Edits for use in Webview/Liveview instances
|
||||||
serde = { version = "1", features = ["derive"], optional = true }
|
serde = { version = "1", features = ["derive"], optional = true }
|
||||||
|
|
||||||
serde_repr = { version = "0.1.7", optional = true }
|
serde_repr = { version = "0.1.7", optional = true }
|
||||||
|
|
|
@ -66,15 +66,15 @@ pub(crate) mod innerlude {
|
||||||
|
|
||||||
pub use crate::innerlude::{
|
pub use crate::innerlude::{
|
||||||
Context, DioxusElement, DomEdit, Element, ElementId, EventPriority, MountType, Mutations,
|
Context, DioxusElement, DomEdit, Element, ElementId, EventPriority, MountType, Mutations,
|
||||||
NodeFactory, Properties, SchedulerMsg, ScopeId, SuspendedContext, TaskHandle, TestDom,
|
NodeFactory, Properties, SchedulerMsg, ScopeChildren, ScopeId, SuspendedContext, TaskHandle,
|
||||||
ThreadsafeVirtualDom, UserEvent, VNode, VirtualDom, FC,
|
TestDom, ThreadsafeVirtualDom, UserEvent, VNode, VirtualDom, FC,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use crate::component::{fc_to_builder, Fragment, Properties, Scope};
|
pub use crate::component::{fc_to_builder, Fragment, Properties, Scope};
|
||||||
pub use crate::context::Context;
|
pub use crate::context::Context;
|
||||||
pub use crate::hooks::*;
|
pub use crate::hooks::*;
|
||||||
pub use crate::innerlude::{DioxusElement, Element, LazyNodes, NodeFactory, FC};
|
pub use crate::innerlude::{DioxusElement, Element, LazyNodes, NodeFactory, ScopeChildren, FC};
|
||||||
pub use crate::nodes::VNode;
|
pub use crate::nodes::VNode;
|
||||||
pub use crate::VirtualDom;
|
pub use crate::VirtualDom;
|
||||||
}
|
}
|
||||||
|
|
|
@ -726,3 +726,65 @@ impl IntoVNode<'_> for Arguments<'_> {
|
||||||
cx.text(self)
|
cx.text(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Access the children elements passed into the component
|
||||||
|
///
|
||||||
|
/// This enables patterns where a component is passed children from its parent.
|
||||||
|
///
|
||||||
|
/// ## Details
|
||||||
|
///
|
||||||
|
/// Unlike React, Dioxus allows *only* lists of children to be passed from parent to child - not arbitrary functions
|
||||||
|
/// or classes. If you want to generate nodes instead of accepting them as a list, consider declaring a closure
|
||||||
|
/// on the props that takes Context.
|
||||||
|
///
|
||||||
|
/// If a parent passes children into a component, the child will always re-render when the parent re-renders. In other
|
||||||
|
/// words, a component cannot be automatically memoized if it borrows nodes from its parent, even if the component's
|
||||||
|
/// props are valid for the static lifetime.
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// const App: FC<()> = |(cx, props)|{
|
||||||
|
/// cx.render(rsx!{
|
||||||
|
/// CustomCard {
|
||||||
|
/// h1 {}
|
||||||
|
/// p {}
|
||||||
|
/// }
|
||||||
|
/// })
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// const CustomCard: FC<()> = |(cx, props)|{
|
||||||
|
/// cx.render(rsx!{
|
||||||
|
/// div {
|
||||||
|
/// h1 {"Title card"}
|
||||||
|
/// {props.children}
|
||||||
|
/// }
|
||||||
|
/// })
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## Notes:
|
||||||
|
///
|
||||||
|
/// This method returns a "ScopeChildren" object. This object is copy-able and preserve the correct lifetime.
|
||||||
|
pub struct ScopeChildren<'a> {
|
||||||
|
root: Option<VNode<'a>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoIterator for &ScopeChildren<'_> {
|
||||||
|
type Item = Self;
|
||||||
|
|
||||||
|
type IntoIter = std::iter::Once<Self>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> IntoVNode<'a> for &ScopeChildren<'a> {
|
||||||
|
fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a> {
|
||||||
|
match &self.root {
|
||||||
|
Some(n) => n.decouple(),
|
||||||
|
None => cx.fragment_from_iter(None as Option<VNode>),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -340,8 +340,6 @@ impl ScopeInner {
|
||||||
let render: &dyn for<'b> Fn(&'b ScopeInner) -> Element<'b> = unsafe { &*self.caller };
|
let render: &dyn for<'b> Fn(&'b ScopeInner) -> Element<'b> = unsafe { &*self.caller };
|
||||||
|
|
||||||
// Todo: see if we can add stronger guarantees around internal bookkeeping and failed component renders.
|
// Todo: see if we can add stronger guarantees around internal bookkeeping and failed component renders.
|
||||||
//
|
|
||||||
// todo!()
|
|
||||||
if let Some(builder) = render(self) {
|
if let Some(builder) = render(self) {
|
||||||
let new_head = builder.into_vnode(NodeFactory {
|
let new_head = builder.into_vnode(NodeFactory {
|
||||||
bump: &self.frames.wip_frame().bump,
|
bump: &self.frames.wip_frame().bump,
|
||||||
|
|
|
@ -64,10 +64,10 @@ fn create() {
|
||||||
"Hello, world!"
|
"Hello, world!"
|
||||||
div {
|
div {
|
||||||
div {
|
div {
|
||||||
Fragment {
|
// Fragment {
|
||||||
"hello"
|
// "hello"
|
||||||
"world"
|
// "world"
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,20 +208,26 @@ fn create_simple() {
|
||||||
#[test]
|
#[test]
|
||||||
fn create_components() {
|
fn create_components() {
|
||||||
static App: FC<()> = |(cx, props)| {
|
static App: FC<()> = |(cx, props)| {
|
||||||
cx.render(rsx! {
|
todo!()
|
||||||
Child { "abc1" }
|
// cx.render(rsx! {
|
||||||
Child { "abc2" }
|
// Child { "abc1" }
|
||||||
Child { "abc3" }
|
// Child { "abc2" }
|
||||||
})
|
// Child { "abc3" }
|
||||||
|
// })
|
||||||
};
|
};
|
||||||
|
|
||||||
static Child: FC<()> = |(cx, props)| {
|
#[derive(Props)]
|
||||||
|
struct ChildProps<'a> {
|
||||||
|
children: ScopeChildren<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn Child<'a>((cx, props): Scope<'a, ChildProps<'a>>) -> Element {
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
h1 {}
|
h1 {}
|
||||||
div { {cx.children()} }
|
div { {&props.children} }
|
||||||
p {}
|
p {}
|
||||||
})
|
})
|
||||||
};
|
}
|
||||||
|
|
||||||
let mut dom = new_dom(App, ());
|
let mut dom = new_dom(App, ());
|
||||||
let mutations = dom.rebuild();
|
let mutations = dom.rebuild();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#![allow(unused, non_upper_case_globals)]
|
#![allow(unused, non_upper_case_globals)]
|
||||||
|
|
||||||
use dioxus::{prelude::*, DomEdit, TestDom};
|
use dioxus::{prelude::*, DomEdit, Mutations, TestDom};
|
||||||
use dioxus_core as dioxus;
|
use dioxus_core as dioxus;
|
||||||
use dioxus_core_macro::*;
|
use dioxus_core_macro::*;
|
||||||
use dioxus_html as dioxus_elements;
|
use dioxus_html as dioxus_elements;
|
||||||
|
|
Loading…
Reference in a new issue