Merge branch 'main' into lendemor/builtins_states
This commit is contained in:
commit
7320425285
@ -328,7 +328,10 @@ _MAPPING: dict = {
|
||||
],
|
||||
"middleware": ["middleware", "Middleware"],
|
||||
"model": ["session", "Model"],
|
||||
"state": ["var"],
|
||||
"state": [
|
||||
"var",
|
||||
"dynamic",
|
||||
],
|
||||
"style": ["Style", "toggle_color_mode"],
|
||||
"utils.imports": ["ImportVar"],
|
||||
"utils.serializers": ["serializer"],
|
||||
|
@ -184,6 +184,7 @@ from .middleware import middleware as middleware
|
||||
from .model import Model as Model
|
||||
from .model import session as session
|
||||
from .page import page as page
|
||||
from .state import dynamic as dynamic
|
||||
from .state import var as var
|
||||
from .style import Style as Style
|
||||
from .style import toggle_color_mode as toggle_color_mode
|
||||
|
@ -30,6 +30,7 @@ from typing import (
|
||||
Set,
|
||||
Tuple,
|
||||
Type,
|
||||
TypeVar,
|
||||
Union,
|
||||
cast,
|
||||
get_args,
|
||||
@ -78,6 +79,7 @@ from reflex.utils import console, format, path_ops, prerequisites, types
|
||||
from reflex.utils.exceptions import (
|
||||
ComputedVarShadowsBaseVars,
|
||||
ComputedVarShadowsStateVar,
|
||||
DynamicComponentInvalidSignature,
|
||||
DynamicRouteArgShadowsStateVar,
|
||||
EventHandlerShadowsBuiltInStateMethod,
|
||||
ImmutableStateError,
|
||||
@ -94,6 +96,9 @@ from reflex.vars import VarData
|
||||
Delta = Dict[str, Any]
|
||||
var = computed_var
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from reflex.components.component import Component
|
||||
|
||||
|
||||
# If the state is this large, it's considered a performance issue.
|
||||
TOO_LARGE_SERIALIZED_STATE = 100 * 1024 # 100kb
|
||||
@ -2085,6 +2090,51 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
||||
return state
|
||||
|
||||
|
||||
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 StateProxy(wrapt.ObjectProxy):
|
||||
"""Proxy of a state instance to control mutability of vars for a background task.
|
||||
|
||||
|
@ -139,3 +139,7 @@ class StateSchemaMismatchError(ReflexError, TypeError):
|
||||
|
||||
class EnvironmentVarValueError(ReflexError, ValueError):
|
||||
"""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