use std::rc::Rc;
use crate::{
Computed, DomComment, DomNode, Value, driver_module::get_driver_dom, struct_mut::ValueMut,
};
pub fn render_value<T: Clone + PartialEq + 'static>(
computed: Computed<T>,
render: impl Fn(T) -> DomNode + 'static,
) -> DomNode {
render_value_option(computed, move |value| -> Option<DomNode> {
Some(render(value))
})
}
pub fn render_value_option<T: Clone + PartialEq + 'static>(
computed: Computed<T>,
render: impl Fn(T) -> Option<DomNode> + 'static,
) -> DomNode {
let render = Rc::new(render);
DomComment::new_marker("v", move |parent_id, comment_id, content| {
let current_node: ValueMut<Option<DomNode>> = ValueMut::new(None);
Some(computed.clone().subscribe({
let render = render.clone();
let content = content.clone();
move |value| {
let new_element = render(value).inspect(|new_element| {
get_driver_dom().insert_before(
parent_id,
new_element.id_dom(),
Some(comment_id),
);
});
content.set(new_element.iter().map(|node| node.id_dom()).collect());
current_node.change(|current| {
*current = new_element;
});
}
}))
})
.into()
}
impl<T: Clone + PartialEq + 'static> Computed<T> {
pub fn render_value(&self, render: impl Fn(T) -> DomNode + 'static) -> DomNode {
render_value(self.clone(), render)
}
pub fn render_value_option(&self, render: impl Fn(T) -> Option<DomNode> + 'static) -> DomNode {
render_value_option(self.clone(), render)
}
}
impl<T: Clone + PartialEq + 'static> Value<T> {
pub fn render_value(&self, render: impl Fn(T) -> DomNode + 'static) -> DomNode {
self.to_computed().render_value(render)
}
pub fn render_value_option(&self, render: impl Fn(T) -> Option<DomNode> + 'static) -> DomNode {
self.to_computed().render_value_option(render)
}
}
pub trait RenderValue<T> {
fn render_value(&self, render: impl Fn(T) -> DomNode + 'static) -> DomNode;
fn render_value_option(&self, render: impl Fn(T) -> Option<DomNode> + 'static) -> DomNode;
}
impl<T: Clone + PartialEq + 'static> RenderValue<T> for Computed<T> {
fn render_value(&self, render: impl Fn(T) -> DomNode + 'static) -> DomNode {
Computed::render_value(self, render)
}
fn render_value_option(&self, render: impl Fn(T) -> Option<DomNode> + 'static) -> DomNode {
Computed::render_value_option(self, render)
}
}
impl<T: Clone + PartialEq + 'static> RenderValue<T> for Value<T> {
fn render_value(&self, render: impl Fn(T) -> DomNode + 'static) -> DomNode {
Value::render_value(self, render)
}
fn render_value_option(&self, render: impl Fn(T) -> Option<DomNode> + 'static) -> DomNode {
Value::render_value_option(self, render)
}
}