44 lines
1.2 KiB
Rust
44 lines
1.2 KiB
Rust
|
|
// content_graph/graph_mini.rs
|
||
|
|
//
|
||
|
|
// Inline ego-network SVG for embedding in content pages.
|
||
|
|
// Static SVG generated at build time — no JS, no Cytoscape, no hydration risk.
|
||
|
|
// Uses inner_html so SSR and WASM produce structurally identical DOM.
|
||
|
|
|
||
|
|
use leptos::prelude::*;
|
||
|
|
|
||
|
|
use super::generated::mini::GRAPH_MINI_SVGS;
|
||
|
|
|
||
|
|
/// Inline ego-network SVG for the given node.
|
||
|
|
///
|
||
|
|
/// Renders nothing if the node has no ego SVG (e.g. orphan nodes or
|
||
|
|
/// non-content nodes that don't get SVGs generated).
|
||
|
|
#[component]
|
||
|
|
pub fn GraphMini(
|
||
|
|
node_id: String,
|
||
|
|
#[prop(optional)] class: Option<String>,
|
||
|
|
) -> impl IntoView {
|
||
|
|
let svg: Option<&'static str> = GRAPH_MINI_SVGS
|
||
|
|
.iter()
|
||
|
|
.find(|(id, _)| *id == node_id.as_str())
|
||
|
|
.map(|(_, svg)| *svg);
|
||
|
|
|
||
|
|
let Some(svg) = svg else {
|
||
|
|
return view! { <></> }.into_any();
|
||
|
|
};
|
||
|
|
|
||
|
|
let wrapper_class = format!(
|
||
|
|
"content-graph-mini-wrapper {}",
|
||
|
|
class.unwrap_or_default()
|
||
|
|
);
|
||
|
|
|
||
|
|
// inner_html with a static &str guarantees SSR == WASM DOM structure.
|
||
|
|
// No reactive signals, no placeholders, no hydration mismatch possible.
|
||
|
|
view! {
|
||
|
|
<div
|
||
|
|
class=wrapper_class
|
||
|
|
aria-hidden="true"
|
||
|
|
inner_html=svg
|
||
|
|
/>
|
||
|
|
}.into_any()
|
||
|
|
}
|