1mod icons;
4
5pub(crate) use icons::*;
6
7use leptos::{ev, prelude::*};
8use thaw_utils::{class_list, mount_style, ArcOneCallback};
9
10#[component]
12pub fn Icon(
13 #[prop(into)]
15 icon: Signal<icondata_core::Icon>,
16 #[prop(into, default = "1em".into())]
19 width: MaybeProp<String>,
20 #[prop(into, default = "1em".into())]
23 height: MaybeProp<String>,
24 #[prop(into, optional)]
26 class: MaybeProp<String>,
27 #[prop(into, optional)]
29 style: Option<Signal<String>>,
30 #[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}