@@ -111,6 +111,7 @@ class Reactive(Generic[ReactiveType]):
111111 compute: Run compute methods when attribute is changed.
112112 recompose: Compose the widget again when the attribute changes.
113113 bindings: Refresh bindings when the reactive changes.
114+ toggle_class: An optional TCSS classname(s) to toggle based on the truthiness of the value.
114115 """
115116
116117 _reactives : ClassVar [dict [str , object ]] = {}
@@ -126,6 +127,7 @@ def __init__(
126127 compute : bool = True ,
127128 recompose : bool = False ,
128129 bindings : bool = False ,
130+ toggle_class : str | None = None ,
129131 ) -> None :
130132 self ._default = default
131133 self ._layout = layout
@@ -135,6 +137,7 @@ def __init__(
135137 self ._run_compute = compute
136138 self ._recompose = recompose
137139 self ._bindings = bindings
140+ self ._toggle_class = toggle_class
138141 self ._owner : Type [MessageTarget ] | None = None
139142 self .name : str
140143
@@ -175,6 +178,7 @@ def _initialize_reactive(self, obj: Reactable, name: str) -> None:
175178 name: Name of attribute.
176179 """
177180 _rich_traceback_omit = True
181+
178182 internal_name = f"_reactive_{ name } "
179183 if hasattr (obj , internal_name ):
180184 # Attribute already has a value
@@ -308,6 +312,11 @@ def _set(self, obj: Reactable, value: ReactiveType, always: bool = False) -> Non
308312 public_validate_function = getattr (obj , f"validate_{ name } " , None )
309313 if callable (public_validate_function ):
310314 value = public_validate_function (value )
315+
316+ # Toggle the classes using the value's truthiness
317+ if (toggle_class := self ._toggle_class ) is not None :
318+ obj .set_class (bool (value ), * toggle_class .split ())
319+
311320 # If the value has changed, or this is the first time setting the value
312321 if always or self ._always_update or current_value != value :
313322 # Store the internal value
@@ -407,6 +416,7 @@ class reactive(Reactive[ReactiveType]):
407416 always_update: Call watchers even when the new value equals the old value.
408417 recompose: Compose the widget again when the attribute changes.
409418 bindings: Refresh bindings when the reactive changes.
419+ toggle_class: An optional TCSS classname(s) to toggle based on the truthiness of the value.
410420 """
411421
412422 def __init__ (
@@ -419,6 +429,7 @@ def __init__(
419429 always_update : bool = False ,
420430 recompose : bool = False ,
421431 bindings : bool = False ,
432+ toggle_class : str | None = None ,
422433 ) -> None :
423434 super ().__init__ (
424435 default ,
@@ -428,6 +439,7 @@ def __init__(
428439 always_update = always_update ,
429440 recompose = recompose ,
430441 bindings = bindings ,
442+ toggle_class = toggle_class ,
431443 )
432444
433445
@@ -439,6 +451,7 @@ class var(Reactive[ReactiveType]):
439451 init: Call watchers on initialize (post mount).
440452 always_update: Call watchers even when the new value equals the old value.
441453 bindings: Refresh bindings when the reactive changes.
454+ toggle_class: An optional TCSS classname(s) to toggle based on the truthiness of the value.
442455 """
443456
444457 def __init__ (
@@ -447,6 +460,7 @@ def __init__(
447460 init : bool = True ,
448461 always_update : bool = False ,
449462 bindings : bool = False ,
463+ toggle_class : str | None = None ,
450464 ) -> None :
451465 super ().__init__ (
452466 default ,
@@ -455,6 +469,7 @@ def __init__(
455469 init = init ,
456470 always_update = always_update ,
457471 bindings = bindings ,
472+ toggle_class = toggle_class ,
458473 )
459474
460475
0 commit comments