diff --git a/tachys/src/reactive_graph/class.rs b/tachys/src/reactive_graph/class.rs index 05abe89c0..a18eb1618 100644 --- a/tachys/src/reactive_graph/class.rs +++ b/tachys/src/reactive_graph/class.rs @@ -1,4 +1,4 @@ -use super::{ReactiveFunction, RenderEffectState, SharedReactiveFunction}; +use super::{ReactiveFunction, RenderEffect, SharedReactiveFunction}; use crate::{html::class::IntoClass, renderer::DomRenderer}; use reactive_graph::{effect::RenderEffect, signal::guards::ReadGuard}; use std::{ @@ -14,7 +14,7 @@ where C::State: 'static, R: DomRenderer, { - type State = RenderEffectState; + type State = RenderEffect; type Cloneable = SharedReactiveFunction; type CloneableOwned = SharedReactiveFunction; @@ -60,9 +60,7 @@ where } fn rebuild(mut self, state: &mut Self::State) { - let prev_effect = std::mem::take(&mut state.0); - let prev_value = prev_effect.as_ref().and_then(|e| e.take_value()); - drop(prev_effect); + let prev_value = state.take_value(); *state = RenderEffect::new_with_value( move |prev| { let value = self.invoke(); @@ -70,12 +68,11 @@ where value.rebuild(&mut state); state } else { - todo!() + unreachable!() } }, prev_value, - ) - .into(); + ); } fn into_cloneable(self) -> Self::Cloneable { @@ -93,7 +90,7 @@ where T: Borrow + 'static, R: DomRenderer, { - type State = RenderEffectState<(R::ClassList, bool)>; + type State = RenderEffect<(R::ClassList, bool)>; type Cloneable = (&'static str, SharedReactiveFunction); type CloneableOwned = (&'static str, SharedReactiveFunction); @@ -159,8 +156,30 @@ where .into() } - fn rebuild(self, _state: &mut Self::State) { - // TODO rebuild? + fn rebuild(self, state: &mut Self::State) { + let (name, mut f) = self; + let prev_value = state.take_value(); + *state = RenderEffect::new_with_value( + move |prev| { + let include = *f.invoke().borrow(); + match prev { + Some((class_list, prev)) => { + if include { + if !prev { + R::add_class(&class_list, name); + } + } else if prev { + R::remove_class(&class_list, name); + } + (class_list.clone(), include) + } + None => { + unreachable!() + } + } + }, + prev_value, + ); } fn into_cloneable(self) -> Self::Cloneable { @@ -178,7 +197,7 @@ where T: Borrow + 'static, R: DomRenderer, { - type State = RenderEffectState<(R::ClassList, bool)>; + type State = RenderEffect<(R::ClassList, bool)>; type Cloneable = (Vec>, SharedReactiveFunction); type CloneableOwned = (Vec>, SharedReactiveFunction); @@ -255,8 +274,35 @@ where .into() } - fn rebuild(self, _state: &mut Self::State) { - // TODO rebuild? + fn rebuild(self, state: &mut Self::State) { + let (names, mut f) = self; + let prev_value = state.take_value(); + + *state = RenderEffect::new_with_value( + move |prev: Option<(R::ClassList, bool)>| { + let include = *f.invoke().borrow(); + match prev { + Some((class_list, prev)) => { + if include { + for name in &names { + if !prev { + R::add_class(&class_list, name); + } + } + } else if prev { + for name in &names { + R::remove_class(&class_list, name); + } + } + (class_list.clone(), include) + } + None => { + unreachable!() + } + } + }, + prev_value, + ); } fn into_cloneable(self) -> Self::Cloneable { @@ -375,7 +421,7 @@ mod stable { C::State: 'static, R: DomRenderer, { - type State = RenderEffectState; + type State = RenderEffect; type Cloneable = Self; type CloneableOwned = Self; @@ -399,8 +445,8 @@ mod stable { (move || self.get()).build(el) } - fn rebuild(self, _state: &mut Self::State) { - // TODO rebuild here? + fn rebuild(self, state: &mut Self::State) { + (move || self.get()).rebuild(state) } fn into_cloneable(self) -> Self::Cloneable { @@ -416,7 +462,7 @@ mod stable { where R: DomRenderer, { - type State = RenderEffectState<(R::ClassList, bool)>; + type State = RenderEffect<(R::ClassList, bool)>; type Cloneable = Self; type CloneableOwned = Self; @@ -446,8 +492,11 @@ mod stable { IntoClass::::build((self.0, move || self.1.get()), el) } - fn rebuild(self, _state: &mut Self::State) { - // TODO rebuild here? + fn rebuild(self, state: &mut Self::State) { + IntoClass::::rebuild( + (self.0, move || self.1.get()), + state, + ) } fn into_cloneable(self) -> Self::Cloneable { @@ -469,7 +518,7 @@ mod stable { C::State: 'static, R: DomRenderer, { - type State = RenderEffectState; + type State = RenderEffect; type Cloneable = Self; type CloneableOwned = Self; @@ -493,8 +542,8 @@ mod stable { (move || self.get()).build(el) } - fn rebuild(self, _state: &mut Self::State) { - // TODO rebuild here? + fn rebuild(self, state: &mut Self::State) { + (move || self.get()).rebuild(state) } fn into_cloneable(self) -> Self::Cloneable { @@ -510,7 +559,7 @@ mod stable { where R: DomRenderer, { - type State = RenderEffectState<(R::ClassList, bool)>; + type State = RenderEffect<(R::ClassList, bool)>; type Cloneable = Self; type CloneableOwned = Self; @@ -540,8 +589,11 @@ mod stable { IntoClass::::build((self.0, move || self.1.get()), el) } - fn rebuild(self, _state: &mut Self::State) { - // TODO rebuild here? + fn rebuild(self, state: &mut Self::State) { + IntoClass::::rebuild( + (self.0, move || self.1.get()), + state, + ) } fn into_cloneable(self) -> Self::Cloneable { @@ -555,7 +607,7 @@ mod stable { }; } - use super::RenderEffectState; + use super::RenderEffect; use crate::{html::class::IntoClass, renderer::DomRenderer}; use reactive_graph::{ computed::{ArcMemo, Memo}, diff --git a/tachys/src/reactive_graph/property.rs b/tachys/src/reactive_graph/property.rs index bca87398c..da59526ca 100644 --- a/tachys/src/reactive_graph/property.rs +++ b/tachys/src/reactive_graph/property.rs @@ -57,8 +57,21 @@ where }) } - fn rebuild(self, _state: &mut Self::State, _key: &str) { - // TODO rebuild + fn rebuild(mut self, state: &mut Self::State, key: &str) { + let prev_value = state.take_value(); + let key = key.to_owned(); + *state = RenderEffect::new_with_value( + move |prev| { + let value = self.invoke(); + if let Some(mut state) = prev { + value.rebuild(&mut state, &key); + state + } else { + unreachable!() + } + }, + prev_value, + ); } fn into_cloneable(self) -> Self::Cloneable { @@ -112,8 +125,8 @@ mod stable { (move || self.get()).build(el, key) } - fn rebuild(self, _state: &mut Self::State, _key: &str) { - // TODO rebuild + fn rebuild(self, state: &mut Self::State, key: &str) { + (move || self.get()).rebuild(state, key) } fn into_cloneable(self) -> Self::Cloneable { @@ -155,8 +168,8 @@ mod stable { (move || self.get()).build(el, key) } - fn rebuild(self, _state: &mut Self::State, _key: &str) { - // TODO rebuild + fn rebuild(self, state: &mut Self::State, key: &str) { + (move || self.get()).rebuild(state, key) } fn into_cloneable(self) -> Self::Cloneable { diff --git a/tachys/src/reactive_graph/style.rs b/tachys/src/reactive_graph/style.rs index 78db663cf..f6ca1271e 100644 --- a/tachys/src/reactive_graph/style.rs +++ b/tachys/src/reactive_graph/style.rs @@ -74,8 +74,25 @@ where }) } - fn rebuild(self, _state: &mut Self::State) { - // TODO rebuild + fn rebuild(self, state: &mut Self::State) { + let (name, mut f) = self; + let prev_value = state.take_value(); + *state = RenderEffect::new_with_value( + move |prev| { + let value = f.invoke().into(); + if let Some(mut state) = prev { + let (style, prev) = &mut state; + if &value != prev { + R::set_css_property(style, name, &value); + } + *prev = value; + state + } else { + unreachable!() + } + }, + prev_value, + ); } fn into_cloneable(self) -> Self::Cloneable { @@ -133,7 +150,21 @@ where }) } - fn rebuild(self, _state: &mut Self::State) {} + fn rebuild(mut self, state: &mut Self::State) { + let prev_value = state.take_value(); + *state = RenderEffect::new_with_value( + move |prev| { + let value = self.invoke(); + if let Some(mut state) = prev { + value.rebuild(&mut state); + state + } else { + unreachable!() + } + }, + prev_value, + ); + } fn into_cloneable(self) -> Self::Cloneable { self.into_shared() @@ -174,8 +205,8 @@ mod stable { (move || self.get()).build(el) } - fn rebuild(self, _state: &mut Self::State) { - // TODO rebuild here? + fn rebuild(self, state: &mut Self::State) { + (move || self.get()).rebuild(el, state) } fn into_cloneable(self) -> Self::Cloneable { @@ -218,8 +249,11 @@ mod stable { IntoStyle::::build((self.0, move || self.1.get()), el) } - fn rebuild(self, _state: &mut Self::State) { - // TODO rebuild here? + fn rebuild(self, state: &mut Self::State) { + IntoStyle::::rebuild( + (self.0, move || self.1.get()), + state, + ) } fn into_cloneable(self) -> Self::Cloneable { @@ -261,8 +295,8 @@ mod stable { (move || self.get()).build(el) } - fn rebuild(self, _state: &mut Self::State) { - // TODO rebuild here? + fn rebuild(self, state: &mut Self::State) { + (move || self.get()).rebuild(state) } fn into_cloneable(self) -> Self::Cloneable { @@ -305,8 +339,11 @@ mod stable { IntoStyle::::build((self.0, move || self.1.get()), el) } - fn rebuild(self, _state: &mut Self::State) { - // TODO rebuild here? + fn rebuild(self, state: &mut Self::State) { + IntoStyle::::rebuild( + (self.0, move || self.1.get()), + state, + ) } fn into_cloneable(self) -> Self::Cloneable {