#![deny(clippy::all)]
#![deny(missing_debug_implementations)]
#![deny(unsafe_code)]
#![deny(non_snake_case)]
#![deny(clippy::cognitive_complexity)]
#![deny(missing_docs)]
#![cfg_attr(documenting, feature(doc_cfg))]
#![cfg_attr(documenting, feature(doc_auto_cfg))]
#![cfg_attr(any(releasing, not(debug_assertions)), deny(dead_code, unused_imports))]
use std::marker::PhantomData;
use bounce::Selector;
use stellation_bridge::links::{Link, PhantomLink};
use stellation_bridge::state::BridgeState;
use stellation_bridge::Bridge;
use yew::prelude::*;
use crate::root::{StellationRoot, StellationRootProps};
pub mod components;
mod root;
pub mod trace;
#[derive(Debug)]
pub struct Renderer<COMP, L = PhantomLink>
where
COMP: BaseComponent,
L: Link,
{
props: COMP::Properties,
bridge_state: Option<BridgeState<L>>,
_marker: PhantomData<COMP>,
}
impl<COMP> Default for Renderer<COMP>
where
COMP: BaseComponent,
COMP::Properties: Default,
{
fn default() -> Self {
Self::new()
}
}
impl<COMP> Renderer<COMP>
where
COMP: BaseComponent,
{
pub fn new() -> Renderer<COMP>
where
COMP::Properties: Default,
{
Self::with_props(Default::default())
}
}
impl<COMP, L> Renderer<COMP, L>
where
COMP: BaseComponent,
L: 'static + Link,
{
pub fn with_props(props: COMP::Properties) -> Renderer<COMP, L> {
Renderer {
props,
bridge_state: None,
_marker: PhantomData,
}
}
pub fn bridge_selector<S, LINK>(self) -> Renderer<COMP, LINK>
where
S: 'static + Selector + AsRef<Bridge<LINK>>,
LINK: 'static + Link,
{
Renderer {
props: self.props,
bridge_state: Some(BridgeState::from_bridge_selector::<S>()),
_marker: PhantomData,
}
}
fn into_yew_renderer(self) -> yew::Renderer<StellationRoot<L>> {
let Self {
props,
bridge_state,
..
} = self;
let children = html! {
<COMP ..props />
};
let props = StellationRootProps {
bridge_state,
children,
};
yew::Renderer::with_props(props)
}
pub fn render(self) {
let renderer = self.into_yew_renderer();
if web_sys::window()
.and_then(|m| m.document())
.and_then(|m| {
m.query_selector(r#"meta[name="stellation-mode"][content="hydrate"]"#)
.ok()
.flatten()
})
.is_some()
{
renderer.hydrate();
} else {
renderer.render();
}
}
}