impulse_thaw/icon/
mod.rs

1// copy https://github.com/Carlosted/leptos-icons
2// leptos updated version causes leptos_icons error
3mod icons;
4
5pub(crate) use icons::*;
6
7use leptos::{ev, prelude::*};
8use thaw_utils::{class_list, mount_style, ArcOneCallback};
9
10/// The Icon component.
11#[component]
12pub fn Icon(
13    /// The icon to render.
14    #[prop(into)]
15    icon: Signal<icondata_core::Icon>,
16    /// The width of the icon (horizontal side length of the square surrounding the icon).
17    /// Defaults to "1em".
18    #[prop(into, default = "1em".into())]
19    width: MaybeProp<String>,
20    /// The height of the icon (vertical side length of the square surrounding the icon).
21    /// Defaults to "1em".
22    #[prop(into, default = "1em".into())]
23    height: MaybeProp<String>,
24    /// HTML class attribute.
25    #[prop(into, optional)]
26    class: MaybeProp<String>,
27    /// HTML style attribute.
28    #[prop(into, optional)]
29    style: Option<Signal<String>>,
30    /// Callback when clicking on the icon.
31    #[prop(optional, into)]
32    on_click: Option<ArcOneCallback<ev::MouseEvent>>,
33) -> impl IntoView {
34    mount_style("icon", include_str!("./icon.css"));
35    let class = class_list!["thaw-icon", class];
36
37    move || {
38        let icon = icon.get();
39
40        let style = match (style.clone(), icon.style) {
41            (Some(a), Some(b)) => Some(ArcMemo::new(move |_| format!("{b} {}", a.get())).into()),
42            (Some(a), None) => Some(a),
43            (None, Some(b)) => Some(b.into()),
44            (None, None) => None,
45        };
46        let width = width.clone();
47        let height = height.clone();
48        let on_click = on_click.clone();
49        let on_click = move |ev| {
50            if let Some(click) = on_click.as_ref() {
51                click(ev);
52            }
53        };
54
55        view! {
56            <svg
57                class=class.clone()
58                style=move || if let Some(s) = style.as_ref() { s.get() } else { String::new() }
59                x=icon.x
60                y=icon.y
61                width=move || width.get()
62                height=move || height.get()
63                viewBox=icon.view_box
64                stroke-linecap=icon.stroke_linecap
65                stroke-linejoin=icon.stroke_linejoin
66                stroke-width=icon.stroke_width
67                stroke=icon.stroke
68                fill=icon.fill.unwrap_or("currentColor")
69                inner_html=icon.data
70                on:click=on_click
71            ></svg>
72        }
73    }
74}