dwui 0.7.4

UI Component library built on the DWIND style crate!
Documentation
use dominator::{clone, events, html, Dom};
use dwind::prelude::*;
use futures_signals::map_ref;
use futures_signals::signal::SignalExt;
use futures_signals::signal_vec::SignalVecExt;
use futures_signals_component_macro::component;
use std::sync::Arc;

#[component(render_fn = pretty_list)]
struct List {
    #[signal_vec]
    #[default(vec ! [])]
    items: Dom,

    #[signal]
    #[default(None)]
    selected_index: Option<usize>,

    #[default(Box::new(|_|{}))]
    item_click_handler: dyn Fn(usize) + 'static,
}

dwgenerate!("li-item-text", "hover:text-woodsmoke-50");
dwgenerate!("li-item-border", "hover:border-woodsmoke-200");

pub fn pretty_list(props: ListProps) -> Dom {
    let ListProps {
        items,
        selected_index,
        item_click_handler,
        apply,
    } = props;

    let item_click_handler = Arc::new(item_click_handler);
    let selected_index = selected_index.broadcast();

    html!("ul", {
        .apply_if(apply.is_some(), |b| b.apply(apply.unwrap()))
        .children_signal_vec(items.enumerate().map(clone!(item_click_handler => move |(index, item)| {
            let selected_signal = map_ref! {
                let selected = selected_index.signal(),
                let index = index.signal() => {
                    index == selected
                }
            }.broadcast();

            html!("li", {
                .dwclass!("li-item-border li-item-text border-l h-6 border-woodsmoke-600 text-woodsmoke-200 cursor-pointer")
                .style("padding-left", "10px")
                .child(item)
                .dwclass_signal!("text-picton-blue-400", selected_signal.signal())
                .dwclass_signal!("hover:text-picton-blue-400", selected_signal.signal())
                .dwclass_signal!("font-bold", selected_signal.signal())
                .dwclass_signal!("border-picton-blue-400", selected_signal.signal())
                .apply(clone!(item_click_handler =>move |b| {
                    b.event(clone!(item_click_handler => move |_: events::Click| {
                        if let Some(idx) = index.get() {
                            item_click_handler(idx);
                        }
                    }))
                }))
            })
        })))
    })
}