implement rx dynamic (#4195)
* implement rx dynamic * dang it darglint * add custom type
This commit is contained in:
parent
a65fc2e90b
commit
3eab2b6e7d
@ -331,6 +331,7 @@ _MAPPING: dict = {
|
|||||||
"var",
|
"var",
|
||||||
"ComponentState",
|
"ComponentState",
|
||||||
"State",
|
"State",
|
||||||
|
"dynamic",
|
||||||
],
|
],
|
||||||
"style": ["Style", "toggle_color_mode"],
|
"style": ["Style", "toggle_color_mode"],
|
||||||
"utils.imports": ["ImportVar"],
|
"utils.imports": ["ImportVar"],
|
||||||
|
@ -184,6 +184,7 @@ from .model import session as session
|
|||||||
from .page import page as page
|
from .page import page as page
|
||||||
from .state import ComponentState as ComponentState
|
from .state import ComponentState as ComponentState
|
||||||
from .state import State as State
|
from .state import State as State
|
||||||
|
from .state import dynamic as dynamic
|
||||||
from .state import var as var
|
from .state import var as var
|
||||||
from .style import Style as Style
|
from .style import Style as Style
|
||||||
from .style import toggle_color_mode as toggle_color_mode
|
from .style import toggle_color_mode as toggle_color_mode
|
||||||
|
@ -30,6 +30,7 @@ from typing import (
|
|||||||
Set,
|
Set,
|
||||||
Tuple,
|
Tuple,
|
||||||
Type,
|
Type,
|
||||||
|
TypeVar,
|
||||||
Union,
|
Union,
|
||||||
cast,
|
cast,
|
||||||
get_args,
|
get_args,
|
||||||
@ -79,6 +80,7 @@ from reflex.utils import console, format, path_ops, prerequisites, types
|
|||||||
from reflex.utils.exceptions import (
|
from reflex.utils.exceptions import (
|
||||||
ComputedVarShadowsBaseVars,
|
ComputedVarShadowsBaseVars,
|
||||||
ComputedVarShadowsStateVar,
|
ComputedVarShadowsStateVar,
|
||||||
|
DynamicComponentInvalidSignature,
|
||||||
DynamicRouteArgShadowsStateVar,
|
DynamicRouteArgShadowsStateVar,
|
||||||
EventHandlerShadowsBuiltInStateMethod,
|
EventHandlerShadowsBuiltInStateMethod,
|
||||||
ImmutableStateError,
|
ImmutableStateError,
|
||||||
@ -2095,6 +2097,51 @@ class State(BaseState):
|
|||||||
is_hydrated: bool = False
|
is_hydrated: bool = False
|
||||||
|
|
||||||
|
|
||||||
|
T = TypeVar("T", bound=BaseState)
|
||||||
|
|
||||||
|
|
||||||
|
def dynamic(func: Callable[[T], Component]):
|
||||||
|
"""Create a dynamically generated components from a state class.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
func: The function to generate the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The dynamically generated component.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
DynamicComponentInvalidSignature: If the function does not have exactly one parameter.
|
||||||
|
DynamicComponentInvalidSignature: If the function does not have a type hint for the state class.
|
||||||
|
"""
|
||||||
|
number_of_parameters = len(inspect.signature(func).parameters)
|
||||||
|
|
||||||
|
func_signature = get_type_hints(func)
|
||||||
|
|
||||||
|
if "return" in func_signature:
|
||||||
|
func_signature.pop("return")
|
||||||
|
|
||||||
|
values = list(func_signature.values())
|
||||||
|
|
||||||
|
if number_of_parameters != 1:
|
||||||
|
raise DynamicComponentInvalidSignature(
|
||||||
|
"The function must have exactly one parameter, which is the state class."
|
||||||
|
)
|
||||||
|
|
||||||
|
if len(values) != 1:
|
||||||
|
raise DynamicComponentInvalidSignature(
|
||||||
|
"You must provide a type hint for the state class in the function."
|
||||||
|
)
|
||||||
|
|
||||||
|
state_class: Type[T] = values[0]
|
||||||
|
|
||||||
|
def wrapper() -> Component:
|
||||||
|
from reflex.components.base.fragment import fragment
|
||||||
|
|
||||||
|
return fragment(state_class._evaluate(lambda state: func(state)))
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
class FrontendEventExceptionState(State):
|
class FrontendEventExceptionState(State):
|
||||||
"""Substate for handling frontend exceptions."""
|
"""Substate for handling frontend exceptions."""
|
||||||
|
|
||||||
|
@ -139,3 +139,7 @@ class StateSchemaMismatchError(ReflexError, TypeError):
|
|||||||
|
|
||||||
class EnvironmentVarValueError(ReflexError, ValueError):
|
class EnvironmentVarValueError(ReflexError, ValueError):
|
||||||
"""Raised when an environment variable is set to an invalid value."""
|
"""Raised when an environment variable is set to an invalid value."""
|
||||||
|
|
||||||
|
|
||||||
|
class DynamicComponentInvalidSignature(ReflexError, TypeError):
|
||||||
|
"""Raised when a dynamic component has an invalid signature."""
|
||||||
|
Loading…
Reference in New Issue
Block a user