Building the DOM
Assembling elements is usually done via function chaining, but every function has a non-chained variant for use in loops or in case ownership gets tricky.
Here's an example of a somewhat involved element:
#![allow(unused)] fn main() { pub use hobo::{prelude::*, create as e}; #[derive(hobo::Element)] pub struct Input { element: e::Div, pub input: e::Input, } impl Input { pub fn new(caption_text: &str, svg: Option<e::Svg>) -> Self { let input = e::input() // shortcut for .attr(web_str::r#type(), web_str::text()) .type_text() .class(css::class! { // some style }); let caption_text = e::div() .text(caption_text) .class(css::class! { // some style }); let mut element = e::div() .class(css::style! { // some style }) .child(input) .child(caption_text); if let Some(svg) = svg { element.add_child( svg.class(css::class! { // some style }) ); } Self { element, input } } } }
.children()
Same as .child()
but can consume an impl IntoIterator
, convenient when taking a Vec<T>
as an argument in list-like element constructors.
There is no .children_signal()
but it could potentially exist - PRs welcome!
Chaining vs non-chaining syntax
Most functions have a chaining syntax, handy when constructing the element, and also non-chaining syntax for use in loops or other contexts. The convention is .<foo>
for chaining and .add_<foo>
for non-chaining. This goes against the more common Rust convention of .with_<foo>
being the chaining syntax, this is because most code will be simple elements constructed in bulk, so most of these calls will be chaining so a shorter name is preferred.
.child()
/.child_signal()
vs.add_child()
/.add_child_signal()
.children()
vs.add_children()
.class()
/.class_tagged()
/.class_typed()
/.class_signal()
vs.set_class()
/.set_class_tagged()
/.set_class_typed()
/.set_class_signal()
.style()
/.style_signal()
vs.set_style()
/.set_style_signal()
.attr()
/.bool_attr()
/.attr_signal()
/.bool_attr_signal()
vs.set_attr()
/.set_bool_attr()
/.set_attr_signal()
/.set_bool_attr_signal()
.<event>()
vs.add_<event>()
.text()
/.text_signal()
vs.set_text()
/.set_text_signal()
.component()
vs.add_component()