icon.rs
⎇
Raw
1//! Renders a glyph from the central [`crate::icons`] registry (Material
2//! Symbols via Iconify) as inline SVG.
3
4use leptos::prelude::*;
5
6use crate::icons::IconName;
7
8/// Folder-shaped glyphs get the accent color; everything else stays muted.
9fn icon_class(name: IconName) -> &'static str {
10 if name.is_folder() {
11 "ic-folder"
12 } else {
13 "ic-muted"
14 }
15}
16
17/// The icon markup, as a plain function rather than a component: a
18/// `#[component]` call costs a reactive owner per instance, which is
19/// measurable at a thousand rows.
20///
21/// `inner_html` rather than a `NodeRef` with an `on_load` callback, for the
22/// same reason: `on_load` is an effect, so a thousand icons meant a thousand
23/// effects. The registry bodies are raw SVG markup (`<path …/>`) and are
24/// injected as-is: the strings are `const`, vendored from the Iconify API,
25/// and never user input.
26pub fn icon_svg(name: IconName, extra: &str) -> impl IntoView + use<> {
27 let mut cls = String::from("icon ");
28 cls.push_str(icon_class(name));
29 if !extra.is_empty() {
30 cls.push(' ');
31 cls.push_str(extra);
32 }
33 view! {
34 <svg
35 class=cls
36 viewBox="0 0 24 24"
37 fill="currentColor"
38 aria-hidden="true"
39 inner_html=name.body()
40 />
41 }
42}
43