fix: icon support event (#116)

This commit is contained in:
luoxiaozero 2024-02-24 15:40:21 +08:00 committed by GitHub
parent 7c01e7e56d
commit 9216e5e2d2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -21,60 +21,75 @@ pub fn Icon(
#[prop(into, optional)] #[prop(into, optional)]
style: Option<MaybeSignal<String>>, style: Option<MaybeSignal<String>>,
) -> impl IntoView { ) -> impl IntoView {
let svg = move || { let icon_style = RwSignal::new(None);
let icon = icon.get(); let icon_x = RwSignal::new(None);
let mut svg = svg::svg(); let icon_y = RwSignal::new(None);
if let Some(class) = class.clone() { let icon_width = RwSignal::new(None);
svg = svg.attr("class", move || class.get()) let icon_height = RwSignal::new(None);
} let icon_view_box = RwSignal::new(None);
let mut svg = match (style.clone(), icon.style) { let icon_stroke_linecap = RwSignal::new(None);
(Some(a), Some(b)) => svg.attr("style", move || format!("{b} {}", a.get())), let icon_stroke_linejoin = RwSignal::new(None);
(Some(a), None) => svg.attr("style", move || a.get()), let icon_stroke_width = RwSignal::new(None);
(None, Some(b)) => svg.attr("style", b), let icon_stroke = RwSignal::new(None);
(None, None) => svg, let icon_fill = RwSignal::new(None);
}; let icon_data = RwSignal::new(None);
if let Some(x) = icon.x { create_render_effect(move |_| {
svg = svg.attr("x", x); let icon = icon.get();
}
if let Some(y) = icon.y { let style = match (style.clone(), icon.style) {
svg = svg.attr("x", y); (Some(a), Some(b)) => Some((move || format!("{b} {}", a.get())).into_attribute()),
} (Some(a), None) => Some((move || a.get()).into_attribute()),
//// The style set by the user overrides the style set by the icon. (None, Some(b)) => Some(b.into_attribute()),
// We ignore the width and height attributes of the icon, even if the user hasn't specified any. (None, None) => None,
svg = svg.attr( };
"width", icon_style.set(style);
match (width.clone(), icon.width) {
(Some(a), _) => (move || a.get()).into_attribute(), icon_x.set(icon.x.map(|x| x.into_attribute()));
_ => "1em".into_attribute(), icon_y.set(icon.y.map(|y| y.into_attribute()));
},
); let width = match (width.clone(), icon.width) {
svg = svg.attr( (Some(a), _) => (move || a.get()).into_attribute(),
"height", _ => "1em".into_attribute(),
match (height.clone(), icon.height) { };
(Some(a), _) => (move || a.get()).into_attribute(), icon_width.set(Some(width));
_ => "1em".into_attribute(),
}, let height = match (height.clone(), icon.height) {
); (Some(a), _) => (move || a.get()).into_attribute(),
if let Some(view_box) = icon.view_box { _ => "1em".into_attribute(),
svg = svg.attr("viewBox", view_box); };
} icon_height.set(Some(height));
if let Some(stroke_linecap) = icon.stroke_linecap {
svg = svg.attr("stroke-linecap", stroke_linecap); icon_view_box.set(icon.view_box.map(|view_box| view_box.into_attribute()));
} icon_stroke_linecap.set(icon.stroke_linecap.map(|a| a.into_attribute()));
if let Some(stroke_linejoin) = icon.stroke_linejoin { icon_stroke_linejoin.set(icon.stroke_linejoin.map(|a| a.into_attribute()));
svg = svg.attr("stroke-linejoin", stroke_linejoin); icon_stroke_width.set(icon.stroke_width.map(|a| a.into_attribute()));
} icon_stroke.set(icon.stroke.map(|a| a.into_attribute()));
if let Some(stroke_width) = icon.stroke_width { icon_fill.set(icon.fill.map(|a| a.into_attribute()));
svg = svg.attr("stroke-width", stroke_width); icon_data.set(Some(icon.data.into_attribute()));
} });
if let Some(stroke) = icon.stroke {
svg = svg.attr("stroke", stroke); view! {
} <svg
svg = svg.attr("fill", icon.fill.unwrap_or("currentColor")); class=class.map(|c| c.get())
svg = svg.attr("role", "graphics-symbol"); style=move || take(icon_style)
svg = svg.inner_html(icon.data); x=move || take(icon_x)
svg y=move || take(icon_y)
}; width=move || take(icon_width)
svg.into_view() height=move || take(icon_height)
viewBox=move || take(icon_view_box)
stroke-linecap=move || take(icon_stroke_linecap)
stroke-linejoin=move || take(icon_stroke_linejoin)
stroke-width=move || take(icon_stroke_width)
stroke=move || take(icon_stroke)
fill=move || take(icon_fill)
inner_html=move || take(icon_data)
>
</svg>
}
}
fn take(signal: RwSignal<Option<Attribute>>) -> Option<Attribute> {
signal.track();
signal.try_update_untracked(|value| value.take()).flatten()
} }