Dynamic attributes, attribute groups
Optional attributes
If component have many different attributes, you not always want to pass all of them. This can be done using attribute groups (AttrGroup). This is a
BtreeMap
of
String
to
AttrGroupValue
items. If you use it as a type in component attributes, it is automatically recognized by
#[component]
and
dom!
macro.
use vertigo::{component, dom, AttrGroup, Value}; #[component] fn MyInput( value: Value<String>, // required /// Optional attributes: id, label mut opt: AttrGroup, ) { let container_id = opt.remove_entry("id"); let label = opt .get("label") .map(|label| dom! { <label>{label}</label> }); dom! { <div {..container_id}> { ..label } <input value={value} /> </div> } } let my_value = Value::new("John".to_string()); dom! { <MyInput value={my_value} opt:id="teges" /> }
You need to use
.remove_entry
because it takes the ownership of the value. Keep in mind that the value can contain a callback which is not cloneable. This also removes the attribute from the group, which is why it needs to be mutable.
Passing attribute group down to contained element
use vertigo::{component, css, dom, AttrGroup, Value}; #[component] fn MyInput(value: Value<String>, input: AttrGroup) { dom! { <div> <label>"First name: "</label> <input value={value} {..input} /> </div> } } let my_value = Value::new("John".to_string()); dom! { <MyInput value={my_value} input:id="first-name" input:css={css!{"color: yellow;"}} /> }
Customizing styles using attribute group
use vertigo::{component, css, dom, AttrGroup, Value}; #[component] fn MyInput(value: Value<String>, input: AttrGroup) { // Base css let css = css!("color: red; background-color: green;"); dom! { <input value={value} {css} {..input} /> } } let my_value = Value::new("John".to_string()); dom! { <MyInput value={my_value} input:id="teges" input:css={css!{"color: yellow;"}} /> }