diff --git a/packages/native-core/tests/custom_element.rs b/packages/native-core/tests/custom_element.rs new file mode 100644 index 000000000..f1285c8cc --- /dev/null +++ b/packages/native-core/tests/custom_element.rs @@ -0,0 +1,195 @@ +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, + _: ::ElementBorrowed<'a>, + parent: Option<::ElementBorrowed<'a>>, + _: Vec<::ElementBorrowed<'a>>, + _: &SendAnyMap, + ) -> bool { + if let Some((parent,)) = parent { + if parent.count != 0 { + self.count += 1; + } + } + true + } + + fn create<'a>( + node_view: NodeView<()>, + node: ::ElementBorrowed<'a>, + parent: Option<::ElementBorrowed<'a>>, + children: Vec<::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::(); + 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); + } +}