dioxus/packages/native-core/tests/custom_element.rs
2023-04-12 10:03:55 -05:00

195 lines
5.2 KiB
Rust

use dioxus::prelude::*;
use dioxus_native_core::{custom_element::CustomElement, prelude::*};
use dioxus_native_core_macro::partial_derive_state;
use shipyard::Component;
use tokio::time::sleep;
#[derive(Debug, Clone, PartialEq, Eq, Default, Component)]
pub struct BlablaState {
count: usize,
}
#[partial_derive_state]
impl State for BlablaState {
type ParentDependencies = (Self,);
type ChildDependencies = ();
type NodeDependencies = ();
const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new()
.with_attrs(AttributeMaskBuilder::Some(&["blabla"]))
.with_element();
fn update<'a>(
&mut self,
_: NodeView,
_: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
_: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
_: &SendAnyMap,
) -> bool {
if let Some((parent,)) = parent {
if parent.count != 0 {
self.count += 1;
}
}
true
}
fn create<'a>(
node_view: NodeView<()>,
node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
context: &SendAnyMap,
) -> Self {
let mut myself = Self::default();
myself.update(node_view, node, parent, children, context);
myself
}
}
mod dioxus_elements {
macro_rules! builder_constructors {
(
$(
$(#[$attr:meta])*
$name:ident {
$(
$(#[$attr_method:meta])*
$fil:ident: $vil:ident,
)*
};
)*
) => {
$(
#[allow(non_camel_case_types)]
$(#[$attr])*
pub struct $name;
impl $name {
pub const TAG_NAME: &'static str = stringify!($name);
pub const NAME_SPACE: Option<&'static str> = None;
$(
pub const $fil: (&'static str, Option<&'static str>, bool) = (stringify!($fil), None, false);
)*
}
impl GlobalAttributes for $name {}
)*
}
}
pub trait GlobalAttributes {}
pub trait SvgAttributes {}
builder_constructors! {
blabla {
};
testing132 {
};
}
}
#[test]
fn native_core_is_okay() {
use std::sync::{Arc, Mutex};
use std::time::Duration;
fn app(cx: Scope) -> Element {
let colors = use_state(cx, || vec!["green", "blue", "red"]);
let padding = use_state(cx, || 10);
use_effect(cx, colors, |colors| async move {
sleep(Duration::from_millis(1000)).await;
colors.with_mut(|colors| colors.reverse());
});
use_effect(cx, padding, |padding| async move {
sleep(Duration::from_millis(10)).await;
padding.with_mut(|padding| {
if *padding < 65 {
*padding += 1;
} else {
*padding = 5;
}
});
});
let _big = colors[0];
let _mid = colors[1];
let _small = colors[2];
cx.render(rsx! {
blabla {
blabla {
testing132 {}
}
}
})
}
let rt = tokio::runtime::Builder::new_current_thread()
.enable_time()
.build()
.unwrap();
rt.block_on(async {
let rdom = Arc::new(Mutex::new(RealDom::new([BlablaState::to_type_erased()])));
rdom.lock()
.unwrap()
.register_custom_element::<TestElement>();
let mut dioxus_state = DioxusState::create(&mut rdom.lock().unwrap());
let mut dom = VirtualDom::new(app);
let mutations = dom.rebuild();
dioxus_state.apply_mutations(&mut rdom.lock().unwrap(), mutations);
let ctx = SendAnyMap::new();
rdom.lock().unwrap().update_state(ctx);
for _ in 0..10 {
dom.wait_for_work().await;
let mutations = dom.render_immediate();
dioxus_state.apply_mutations(&mut rdom.lock().unwrap(), mutations);
let ctx = SendAnyMap::new();
rdom.lock().unwrap().update_state(ctx);
}
});
}
struct TestElement {
root: NodeId,
}
impl CustomElement for TestElement {
const NAME: &'static str = "blabla";
fn create(dom: &mut RealDom<()>) -> Self {
let root = dom.create_node(ElementNode {
tag: "shadow_root".into(),
namespace: None,
attributes: Default::default(),
listeners: Default::default(),
});
Self { root: root.id() }
}
fn root(&self) -> NodeId {
self.root
}
fn attributes_changed(
&mut self,
_dom: &mut RealDom<()>,
attributes: &dioxus_native_core::node_ref::AttributeMask,
) {
println!("attributes_changed");
println!("{:?}", attributes);
}
}