euv_core/vdom/node/fn.rs
1use crate::*;
2
3/// Constructs a `VirtualNode::Dynamic` from a render closure with hook context management.
4///
5/// This function replaces the boilerplate that was previously generated inline
6/// by the `html!` macro for every `Dynamic`, `If`, `Match`, and `For` node.
7/// The macro now emits `euv_core::create_dynamic_node(render_fn)` instead of
8/// the full `HookContext` + `DynamicNode` + `render_fn` setup block.
9///
10/// # Arguments
11///
12/// - `FnMut() -> VirtualNode + 'static` - The render closure that produces
13/// a virtual node tree. Called on initial render and on every signal update.
14///
15/// # Returns
16///
17/// - `VirtualNode` - A `VirtualNode::Dynamic` wrapping the render closure
18/// with a fresh `HookContext`.
19pub fn create_dynamic_node<F>(mut render_fn: F) -> VirtualNode
20where
21 F: FnMut() -> VirtualNode + 'static,
22{
23 let hook_context: HookContext = create_hook_context();
24 let render_fn: Rc<RefCell<dyn FnMut() -> VirtualNode>> = {
25 let mut hook_context: HookContext = hook_context;
26 Rc::new(RefCell::new(move || {
27 hook_context.reset_hook_index();
28 render_fn()
29 }))
30 };
31 let mut dynamic_node: DynamicNode = DynamicNode::default();
32 dynamic_node.set_render_fn(render_fn);
33 dynamic_node.set_hook_context(hook_context);
34 VirtualNode::Dynamic(dynamic_node)
35}
36
37/// Constructs a `VirtualNode::Dynamic` for match expressions where arm hook
38/// isolation is required. The render closure receives a `&mut HookContext`
39/// so it can call `set_arm_changed` before each arm body.
40///
41/// This function replaces the inline `HookContext` + `DynamicNode` setup that
42/// was previously generated for match nodes, where the hook context had to be
43/// accessible inside the render closure for arm switching.
44///
45/// # Arguments
46///
47/// - `FnMut(&mut HookContext) -> VirtualNode + 'static` - The render closure
48/// that receives a mutable reference to the hook context. The closure is
49/// responsible for calling `set_arm_changed` before each match arm.
50///
51/// # Returns
52///
53/// - `VirtualNode` - A `VirtualNode::Dynamic` wrapping the render closure
54/// with a fresh `HookContext`.
55pub fn create_dynamic_node_with_context<F>(mut render_fn: F) -> VirtualNode
56where
57 F: FnMut(&mut HookContext) -> VirtualNode + 'static,
58{
59 let hook_context: HookContext = create_hook_context();
60 let render_fn: Rc<RefCell<dyn FnMut() -> VirtualNode>> = {
61 let mut hook_context: HookContext = hook_context;
62 Rc::new(RefCell::new(move || {
63 hook_context.reset_hook_index();
64 render_fn(&mut hook_context)
65 }))
66 };
67 let mut dynamic_node: DynamicNode = DynamicNode::default();
68 dynamic_node.set_render_fn(render_fn);
69 dynamic_node.set_hook_context(hook_context);
70 VirtualNode::Dynamic(dynamic_node)
71}