move hybrid_property to experimental namespace
This commit is contained in:
parent
c8527676d4
commit
1b3c82dcee
reflex
tests/integration
@ -11,6 +11,7 @@ from ..utils.console import warn
|
||||
from . import hooks as hooks
|
||||
from .assets import asset as asset
|
||||
from .client_state import ClientStateVar as ClientStateVar
|
||||
from .hybrid_property import hybrid_property as hybrid_property
|
||||
from .layout import layout as layout
|
||||
from .misc import run_in_thread as run_in_thread
|
||||
|
||||
@ -69,4 +70,5 @@ _x = ExperimentalNamespace(
|
||||
PropsBase=PropsBase,
|
||||
run_in_thread=run_in_thread,
|
||||
code_block=code_block,
|
||||
hybrid_property=hybrid_property,
|
||||
)
|
||||
|
49
reflex/experimental/hybrid_property.py
Normal file
49
reflex/experimental/hybrid_property.py
Normal file
@ -0,0 +1,49 @@
|
||||
"""hybrid_property decorator which functions like a normal python property but additionally allows (class-level) access from the frontend. You can use the same code for frontend and backend, or implement 2 different methods."""
|
||||
|
||||
from typing import Any, Callable
|
||||
|
||||
from reflex.utils.types import Self, override
|
||||
from reflex.vars.base import Var
|
||||
|
||||
|
||||
class HybridProperty(property):
|
||||
"""A hybrid property that can also be used in frontend/as var."""
|
||||
|
||||
# The optional var function for the property.
|
||||
_var: Callable[[Any], Var] | None = None
|
||||
|
||||
@override
|
||||
def __get__(self, instance: Any, owner: type | None = None, /) -> Any:
|
||||
"""Get the value of the property. If the property is not bound to an instance return a frontend Var.
|
||||
|
||||
Args:
|
||||
instance: The instance of the class accessing this property.
|
||||
owner: The class that this descriptor is attached to.
|
||||
|
||||
Returns:
|
||||
The value of the property or a frontend Var.
|
||||
"""
|
||||
if instance is not None:
|
||||
return super().__get__(instance, owner)
|
||||
if self._var is not None:
|
||||
# Call custom var function if set
|
||||
return self._var(owner)
|
||||
else:
|
||||
# Call the property getter function if no custom var function is set
|
||||
assert self.fget is not None
|
||||
return self.fget(owner)
|
||||
|
||||
def var(self, func: Callable[[Any], Var]) -> Self:
|
||||
"""Set the (optional) var function for the property.
|
||||
|
||||
Args:
|
||||
func: The var function to set.
|
||||
|
||||
Returns:
|
||||
The property instance with the var function set.
|
||||
"""
|
||||
self._var = func
|
||||
return self
|
||||
|
||||
|
||||
hybrid_property = HybridProperty
|
@ -7,7 +7,6 @@ from .base import VarData as VarData
|
||||
from .base import field as field
|
||||
from .base import get_unique_variable_name as get_unique_variable_name
|
||||
from .base import get_uuid_string_var as get_uuid_string_var
|
||||
from .base import hybrid_property as hybrid_property
|
||||
from .base import var_operation as var_operation
|
||||
from .base import var_operation_return as var_operation_return
|
||||
from .function import FunctionStringVar as FunctionStringVar
|
||||
|
@ -2949,49 +2949,3 @@ def field(value: T) -> Field[T]:
|
||||
The Field.
|
||||
"""
|
||||
return value # type: ignore
|
||||
|
||||
|
||||
VAR_CALLABLE = Callable[[Any], Var]
|
||||
|
||||
|
||||
class HybridProperty(property):
|
||||
"""A hybrid property that can also be used in frontend/as var."""
|
||||
|
||||
# The optional var function for the property.
|
||||
_var: VAR_CALLABLE | None = None
|
||||
|
||||
@override
|
||||
def __get__(self, instance: Any, owner: type | None = None, /) -> Any:
|
||||
"""Get the value of the property. If the property is not bound to an instance return a frontend Var.
|
||||
|
||||
Args:
|
||||
instance: The instance of the class accessing this property.
|
||||
owner: The class that this descriptor is attached to.
|
||||
|
||||
Returns:
|
||||
The value of the property or a frontend Var.
|
||||
"""
|
||||
if instance is not None:
|
||||
return super().__get__(instance, owner)
|
||||
if self._var is not None:
|
||||
# Call custom var function if set
|
||||
return self._var(owner)
|
||||
else:
|
||||
# Call the property getter function if no custom var function is set
|
||||
assert self.fget is not None
|
||||
return self.fget(owner)
|
||||
|
||||
def var(self, func: VAR_CALLABLE) -> Self:
|
||||
"""Set the (optional) var function for the property.
|
||||
|
||||
Args:
|
||||
func: The var function to set.
|
||||
|
||||
Returns:
|
||||
The property instance with the var function set.
|
||||
"""
|
||||
self._var = func
|
||||
return self
|
||||
|
||||
|
||||
hybrid_property = HybridProperty
|
||||
|
@ -14,7 +14,8 @@ from reflex.testing import DEFAULT_TIMEOUT, AppHarness, WebDriver
|
||||
def HybridProperties():
|
||||
"""Test app for hybrid properties."""
|
||||
import reflex as rx
|
||||
from reflex.vars import Var, hybrid_property
|
||||
from reflex.experimental import hybrid_property
|
||||
from reflex.vars import Var
|
||||
|
||||
class State(rx.State):
|
||||
first_name: str = "John"
|
||||
@ -71,7 +72,7 @@ def HybridProperties():
|
||||
rx.text(f"has_last_name: {State.has_last_name}", id="has_last_name"),
|
||||
rx.input(
|
||||
value=State.last_name,
|
||||
on_change=State.set_last_name, # type: ignore
|
||||
on_change=State.setvar("last_name"),
|
||||
id="set_last_name",
|
||||
),
|
||||
),
|
||||
|
Loading…
Reference in New Issue
Block a user