Crate yew_html_ext

source ·
Expand description

This crate provides handy extensions to Yew’s HTML macros. It provides html! and html_nested! macros that are fully backwards-compatible with the original ones defined in Yew, meaning all one has to do to start using this crate is just change the uses/imports of yew::html{_nested} to yew_html_ext::html{_nested}.

§New syntax

§for loops

The syntax is the same as of Rust’s for loops, the body of the loop can contain 0 or more nodes.

use yew::{Properties, function_component, html::Html};
use yew_html_ext::html;

#[derive(PartialEq, Properties)]
struct CountdownProps {
    n: usize,
}

#[function_component]
fn Countdown(props: &CountdownProps) -> Html {
    html! {
        <div>
            for i in (0 .. props.n).rev() {
                <h2>{ i }</h2>
                <br />
            }
        </div>
    }
}

In a list of nodes all nodes must have unique keys or have no key, which is why using a constant to specify a key of a node in a loop is dangerous: if the loop iterates more than once, the generated list will have repeated keys; as a best-effort attempt to prevent such cases, the macro disallows specifying literals or constants as keys

html! {
    <div>
        for i in (0 .. props.n).rev() {
            <h2 key="number" /* nuh-uh */>{ i }</h2>
            <br />
        }
    </div>
}

§match nodes

The syntax is the same as of Rust’s match expressions; the body of a match arm must have exactly 1 node.

use yew::{Properties, function_component, html::Html};
use yew_html_ext::html;
use std::cmp::Ordering;

#[derive(PartialEq, Properties)]
struct ComparisonProps {
    int1: usize,
    int2: usize,
}

#[function_component]
fn Comparison(props: &ComparisonProps) -> Html {
    html! {
        match props.int1.cmp(&props.int2) {
            Ordering::Less => { '<' },
            Ordering::Equal => { '=' },
            Ordering::Greater => { '>' },
        }
    }
}

§let bindings

Normal Rust’s let bindings, including let-else structures, are supported with the same syntax.

use yew::{Properties, function_component, html::Html};
use yew_html_ext::html;
use std::{fs::read_dir, path::PathBuf};

#[derive(PartialEq, Properties)]
struct DirProps {
    path: PathBuf,
}

#[function_component]
fn Dir(props: &DirProps) -> Html {
    html! {
        <ul>
            let Ok(iter) = read_dir(&props.path) else {
                return html!("oops :P")
            };
            for entry in iter {
                let Ok(entry) = entry else {
                    return html!("oops :p")
                };
                <li>{ format!("{:?}", entry.path()) }</li>
            }
        </ul>
    }
}

Macros§