Merge remote-tracking branch 'upstream/main' into fix-wrong-hook

This commit is contained in:
Benedikt Bartscher 2024-11-05 00:00:21 +01:00
commit ddbab3f180
No known key found for this signature in database
50 changed files with 602 additions and 468 deletions

View File

@ -178,11 +178,6 @@ export const applyEvent = async (event, socket) => {
return false; return false;
} }
if (event.name == "_console") {
console.log(event.payload.message);
return false;
}
if (event.name == "_remove_cookie") { if (event.name == "_remove_cookie") {
cookies.remove(event.payload.key, { ...event.payload.options }); cookies.remove(event.payload.key, { ...event.payload.options });
queueEventIfSocketExists(initialEvents(), socket); queueEventIfSocketExists(initialEvents(), socket);
@ -213,12 +208,6 @@ export const applyEvent = async (event, socket) => {
return false; return false;
} }
if (event.name == "_set_clipboard") {
const content = event.payload.content;
navigator.clipboard.writeText(content);
return false;
}
if (event.name == "_download") { if (event.name == "_download") {
const a = document.createElement("a"); const a = document.createElement("a");
a.hidden = true; a.hidden = true;
@ -233,11 +222,6 @@ export const applyEvent = async (event, socket) => {
return false; return false;
} }
if (event.name == "_alert") {
alert(event.payload.message);
return false;
}
if (event.name == "_set_focus") { if (event.name == "_set_focus") {
const ref = const ref =
event.payload.ref in refs ? refs[event.payload.ref] : event.payload.ref; event.payload.ref in refs ? refs[event.payload.ref] : event.payload.ref;
@ -254,6 +238,25 @@ export const applyEvent = async (event, socket) => {
return false; return false;
} }
if (event.name == "_call_function") {
try {
const eval_result = event.payload.function();
if (event.payload.callback) {
if (!!eval_result && typeof eval_result.then === "function") {
event.payload.callback(await eval_result);
} else {
event.payload.callback(eval_result);
}
}
} catch (e) {
console.log("_call_function", e);
if (window && window?.onerror) {
window.onerror(e.message, null, null, null, e);
}
}
return false;
}
if (event.name == "_call_script") { if (event.name == "_call_script") {
try { try {
const eval_result = eval(event.payload.javascript_code); const eval_result = eval(event.payload.javascript_code);

View File

@ -303,10 +303,13 @@ _MAPPING: dict = {
"EventHandler", "EventHandler",
"background", "background",
"call_script", "call_script",
"call_function",
"run_script",
"clear_local_storage", "clear_local_storage",
"clear_session_storage", "clear_session_storage",
"console_log", "console_log",
"download", "download",
"noop",
"prevent_default", "prevent_default",
"redirect", "redirect",
"remove_cookie", "remove_cookie",

View File

@ -155,17 +155,20 @@ from .constants import Env as Env
from .event import EventChain as EventChain from .event import EventChain as EventChain
from .event import EventHandler as EventHandler from .event import EventHandler as EventHandler
from .event import background as background from .event import background as background
from .event import call_function as call_function
from .event import call_script as call_script from .event import call_script as call_script
from .event import clear_local_storage as clear_local_storage from .event import clear_local_storage as clear_local_storage
from .event import clear_session_storage as clear_session_storage from .event import clear_session_storage as clear_session_storage
from .event import console_log as console_log from .event import console_log as console_log
from .event import download as download from .event import download as download
from .event import event as event from .event import event as event
from .event import noop as noop
from .event import prevent_default as prevent_default from .event import prevent_default as prevent_default
from .event import redirect as redirect from .event import redirect as redirect
from .event import remove_cookie as remove_cookie from .event import remove_cookie as remove_cookie
from .event import remove_local_storage as remove_local_storage from .event import remove_local_storage as remove_local_storage
from .event import remove_session_storage as remove_session_storage from .event import remove_session_storage as remove_session_storage
from .event import run_script as run_script
from .event import scroll_to as scroll_to from .event import scroll_to as scroll_to
from .event import set_clipboard as set_clipboard from .event import set_clipboard as set_clipboard
from .event import set_focus as set_focus from .event import set_focus as set_focus

View File

@ -8,7 +8,7 @@ from __future__ import annotations
from typing import Literal from typing import Literal
from reflex.components.component import Component from reflex.components.component import Component
from reflex.event import EventHandler, empty_event from reflex.event import EventHandler, no_args_event_spec
from reflex.vars.base import LiteralVar, Var from reflex.vars.base import LiteralVar, Var
@ -35,13 +35,13 @@ class Script(Component):
) )
# Triggered when the script is loading # Triggered when the script is loading
on_load: EventHandler[empty_event] on_load: EventHandler[no_args_event_spec]
# Triggered when the script has loaded # Triggered when the script has loaded
on_ready: EventHandler[empty_event] on_ready: EventHandler[no_args_event_spec]
# Triggered when the script has errored # Triggered when the script has errored
on_error: EventHandler[empty_event] on_error: EventHandler[no_args_event_spec]
@classmethod @classmethod
def create(cls, *children, **props) -> Component: def create(cls, *children, **props) -> Component:

View File

@ -47,8 +47,8 @@ from reflex.event import (
EventVar, EventVar,
call_event_fn, call_event_fn,
call_event_handler, call_event_handler,
empty_event,
get_handler_args, get_handler_args,
no_args_event_spec,
) )
from reflex.style import Style, format_as_emotion from reflex.style import Style, format_as_emotion
from reflex.utils import format, imports, types from reflex.utils import format, imports, types
@ -637,21 +637,21 @@ class Component(BaseComponent, ABC):
""" """
default_triggers = { default_triggers = {
EventTriggers.ON_FOCUS: empty_event, EventTriggers.ON_FOCUS: no_args_event_spec,
EventTriggers.ON_BLUR: empty_event, EventTriggers.ON_BLUR: no_args_event_spec,
EventTriggers.ON_CLICK: empty_event, EventTriggers.ON_CLICK: no_args_event_spec,
EventTriggers.ON_CONTEXT_MENU: empty_event, EventTriggers.ON_CONTEXT_MENU: no_args_event_spec,
EventTriggers.ON_DOUBLE_CLICK: empty_event, EventTriggers.ON_DOUBLE_CLICK: no_args_event_spec,
EventTriggers.ON_MOUSE_DOWN: empty_event, EventTriggers.ON_MOUSE_DOWN: no_args_event_spec,
EventTriggers.ON_MOUSE_ENTER: empty_event, EventTriggers.ON_MOUSE_ENTER: no_args_event_spec,
EventTriggers.ON_MOUSE_LEAVE: empty_event, EventTriggers.ON_MOUSE_LEAVE: no_args_event_spec,
EventTriggers.ON_MOUSE_MOVE: empty_event, EventTriggers.ON_MOUSE_MOVE: no_args_event_spec,
EventTriggers.ON_MOUSE_OUT: empty_event, EventTriggers.ON_MOUSE_OUT: no_args_event_spec,
EventTriggers.ON_MOUSE_OVER: empty_event, EventTriggers.ON_MOUSE_OVER: no_args_event_spec,
EventTriggers.ON_MOUSE_UP: empty_event, EventTriggers.ON_MOUSE_UP: no_args_event_spec,
EventTriggers.ON_SCROLL: empty_event, EventTriggers.ON_SCROLL: no_args_event_spec,
EventTriggers.ON_MOUNT: empty_event, EventTriggers.ON_MOUNT: no_args_event_spec,
EventTriggers.ON_UNMOUNT: empty_event, EventTriggers.ON_UNMOUNT: no_args_event_spec,
} }
# Look for component specific triggers, # Look for component specific triggers,
@ -662,7 +662,7 @@ class Component(BaseComponent, ABC):
annotation = field.annotation annotation = field.annotation
if (metadata := getattr(annotation, "__metadata__", None)) is not None: if (metadata := getattr(annotation, "__metadata__", None)) is not None:
args_spec = metadata[0] args_spec = metadata[0]
default_triggers[field.name] = args_spec or (empty_event) # type: ignore default_triggers[field.name] = args_spec or (no_args_event_spec) # type: ignore
return default_triggers return default_triggers
def __repr__(self) -> str: def __repr__(self) -> str:
@ -1723,7 +1723,7 @@ class CustomComponent(Component):
value = self._create_event_chain( value = self._create_event_chain(
value=value, value=value,
args_spec=event_triggers_in_component_declaration.get( args_spec=event_triggers_in_component_declaration.get(
key, empty_event key, no_args_event_spec
), ),
key=key, key=key,
) )

View File

@ -6,7 +6,7 @@ from typing import Dict, List, Tuple, Union
from reflex.components.base.fragment import Fragment from reflex.components.base.fragment import Fragment
from reflex.components.tags.tag import Tag from reflex.components.tags.tag import Tag
from reflex.event import EventChain, EventHandler, identity_event from reflex.event import EventChain, EventHandler, passthrough_event_spec
from reflex.utils.format import format_prop, wrap from reflex.utils.format import format_prop, wrap
from reflex.utils.imports import ImportVar from reflex.utils.imports import ImportVar
from reflex.vars import get_unique_variable_name from reflex.vars import get_unique_variable_name
@ -20,7 +20,7 @@ class Clipboard(Fragment):
targets: Var[List[str]] targets: Var[List[str]]
# Called when the user pastes data into the document. Data is a list of tuples of (mime_type, data). Binary types will be base64 encoded as a data uri. # Called when the user pastes data into the document. Data is a list of tuples of (mime_type, data). Binary types will be base64 encoded as a data uri.
on_paste: EventHandler[identity_event(List[Tuple[str, str]])] on_paste: EventHandler[passthrough_event_spec(List[Tuple[str, str]])]
# Save the original event actions for the on_paste event. # Save the original event actions for the on_paste event.
on_paste_event_actions: Var[Dict[str, Union[bool, int]]] on_paste_event_actions: Var[Dict[str, Union[bool, int]]]

View File

@ -6,7 +6,9 @@
from typing import Any, Dict, List, Optional, Union, overload from typing import Any, Dict, List, Optional, Union, overload
from reflex.components.base.fragment import Fragment from reflex.components.base.fragment import Fragment
from reflex.event import EventType from reflex.event import (
EventType,
)
from reflex.style import Style from reflex.style import Style
from reflex.utils.imports import ImportVar from reflex.utils.imports import ImportVar
from reflex.vars.base import Var from reflex.vars.base import Var

View File

@ -6,7 +6,7 @@ from typing import Any, Type, Union
from reflex.components.component import Component from reflex.components.component import Component
from reflex.constants import EventTriggers from reflex.constants import EventTriggers
from reflex.event import EventHandler, empty_event from reflex.event import EventHandler, no_args_event_spec
from reflex.vars import VarData from reflex.vars import VarData
from reflex.vars.base import Var from reflex.vars.base import Var
@ -46,7 +46,7 @@ class DebounceInput(Component):
element: Var[Type[Component]] element: Var[Type[Component]]
# Fired when the input value changes # Fired when the input value changes
on_change: EventHandler[empty_event] on_change: EventHandler[no_args_event_spec]
@classmethod @classmethod
def create(cls, *children: Component, **props: Any) -> Component: def create(cls, *children: Component, **props: Any) -> Component:

View File

@ -22,8 +22,8 @@ from reflex.event import (
EventHandler, EventHandler,
EventSpec, EventSpec,
call_event_fn, call_event_fn,
call_script,
parse_args_spec, parse_args_spec,
run_script,
) )
from reflex.utils import format from reflex.utils import format
from reflex.utils.imports import ImportVar from reflex.utils.imports import ImportVar
@ -106,8 +106,8 @@ def clear_selected_files(id_: str = DEFAULT_UPLOAD_ID) -> EventSpec:
""" """
# UploadFilesProvider assigns a special function to clear selected files # UploadFilesProvider assigns a special function to clear selected files
# into the shared global refs object to make it accessible outside a React # into the shared global refs object to make it accessible outside a React
# component via `call_script` (otherwise backend could never clear files). # component via `run_script` (otherwise backend could never clear files).
return call_script(f"refs['__clear_selected_files']({id_!r})") return run_script(f"refs['__clear_selected_files']({id_!r})")
def cancel_upload(upload_id: str) -> EventSpec: def cancel_upload(upload_id: str) -> EventSpec:
@ -119,7 +119,7 @@ def cancel_upload(upload_id: str) -> EventSpec:
Returns: Returns:
An event spec that cancels the upload when triggered. An event spec that cancels the upload when triggered.
""" """
return call_script( return run_script(
f"upload_controllers[{str(LiteralVar.create(upload_id))}]?.abort()" f"upload_controllers[{str(LiteralVar.create(upload_id))}]?.abort()"
) )

View File

@ -10,7 +10,7 @@ from typing_extensions import TypedDict
from reflex.base import Base from reflex.base import Base
from reflex.components.component import Component, NoSSRComponent from reflex.components.component import Component, NoSSRComponent
from reflex.components.literals import LiteralRowMarker from reflex.components.literals import LiteralRowMarker
from reflex.event import EventHandler, empty_event, identity_event from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
from reflex.utils import console, format, types from reflex.utils import console, format, types
from reflex.utils.imports import ImportDict, ImportVar from reflex.utils.imports import ImportDict, ImportVar
from reflex.utils.serializers import serializer from reflex.utils.serializers import serializer
@ -284,56 +284,58 @@ class DataEditor(NoSSRComponent):
theme: Var[Union[DataEditorTheme, Dict]] theme: Var[Union[DataEditorTheme, Dict]]
# Fired when a cell is activated. # Fired when a cell is activated.
on_cell_activated: EventHandler[identity_event(Tuple[int, int])] on_cell_activated: EventHandler[passthrough_event_spec(Tuple[int, int])]
# Fired when a cell is clicked. # Fired when a cell is clicked.
on_cell_clicked: EventHandler[identity_event(Tuple[int, int])] on_cell_clicked: EventHandler[passthrough_event_spec(Tuple[int, int])]
# Fired when a cell is right-clicked. # Fired when a cell is right-clicked.
on_cell_context_menu: EventHandler[identity_event(Tuple[int, int])] on_cell_context_menu: EventHandler[passthrough_event_spec(Tuple[int, int])]
# Fired when a cell is edited. # Fired when a cell is edited.
on_cell_edited: EventHandler[identity_event(Tuple[int, int], GridCell)] on_cell_edited: EventHandler[passthrough_event_spec(Tuple[int, int], GridCell)]
# Fired when a group header is clicked. # Fired when a group header is clicked.
on_group_header_clicked: EventHandler[identity_event(Tuple[int, int], GridCell)] on_group_header_clicked: EventHandler[
passthrough_event_spec(Tuple[int, int], GridCell)
]
# Fired when a group header is right-clicked. # Fired when a group header is right-clicked.
on_group_header_context_menu: EventHandler[ on_group_header_context_menu: EventHandler[
identity_event(int, GroupHeaderClickedEventArgs) passthrough_event_spec(int, GroupHeaderClickedEventArgs)
] ]
# Fired when a group header is renamed. # Fired when a group header is renamed.
on_group_header_renamed: EventHandler[identity_event(str, str)] on_group_header_renamed: EventHandler[passthrough_event_spec(str, str)]
# Fired when a header is clicked. # Fired when a header is clicked.
on_header_clicked: EventHandler[identity_event(Tuple[int, int])] on_header_clicked: EventHandler[passthrough_event_spec(Tuple[int, int])]
# Fired when a header is right-clicked. # Fired when a header is right-clicked.
on_header_context_menu: EventHandler[identity_event(Tuple[int, int])] on_header_context_menu: EventHandler[passthrough_event_spec(Tuple[int, int])]
# Fired when a header menu item is clicked. # Fired when a header menu item is clicked.
on_header_menu_click: EventHandler[identity_event(int, Rectangle)] on_header_menu_click: EventHandler[passthrough_event_spec(int, Rectangle)]
# Fired when an item is hovered. # Fired when an item is hovered.
on_item_hovered: EventHandler[identity_event(Tuple[int, int])] on_item_hovered: EventHandler[passthrough_event_spec(Tuple[int, int])]
# Fired when a selection is deleted. # Fired when a selection is deleted.
on_delete: EventHandler[identity_event(GridSelection)] on_delete: EventHandler[passthrough_event_spec(GridSelection)]
# Fired when editing is finished. # Fired when editing is finished.
on_finished_editing: EventHandler[ on_finished_editing: EventHandler[
identity_event(Union[GridCell, None], tuple[int, int]) passthrough_event_spec(Union[GridCell, None], tuple[int, int])
] ]
# Fired when a row is appended. # Fired when a row is appended.
on_row_appended: EventHandler[empty_event] on_row_appended: EventHandler[no_args_event_spec]
# Fired when the selection is cleared. # Fired when the selection is cleared.
on_selection_cleared: EventHandler[empty_event] on_selection_cleared: EventHandler[no_args_event_spec]
# Fired when a column is resized. # Fired when a column is resized.
on_column_resize: EventHandler[identity_event(GridColumn, int)] on_column_resize: EventHandler[passthrough_event_spec(GridColumn, int)]
def add_imports(self) -> ImportDict: def add_imports(self) -> ImportDict:
"""Add imports for the component. """Add imports for the component.

View File

@ -14,7 +14,7 @@ from reflex.components.el.elements.forms import Button
from reflex.components.lucide.icon import Icon from reflex.components.lucide.icon import Icon
from reflex.components.props import NoExtrasAllowedProps from reflex.components.props import NoExtrasAllowedProps
from reflex.components.radix.themes.layout.box import Box from reflex.components.radix.themes.layout.box import Box
from reflex.event import call_script, set_clipboard from reflex.event import run_script, set_clipboard
from reflex.style import Style from reflex.style import Style
from reflex.utils.exceptions import VarTypeError from reflex.utils.exceptions import VarTypeError
from reflex.utils.imports import ImportVar from reflex.utils.imports import ImportVar
@ -30,7 +30,7 @@ def copy_script() -> Any:
Returns: Returns:
Any: The result of calling the script. Any: The result of calling the script.
""" """
return call_script( return run_script(
f""" f"""
// Event listener for the parent click // Event listener for the parent click
document.addEventListener('click', function(event) {{ document.addEventListener('click', function(event) {{
@ -68,7 +68,7 @@ document.addEventListener('click', function(event) {{
}} else {{ }} else {{
// console.error('Parent element not found.'); // console.error('Parent element not found.');
}} }}
}}); }})
""" """
) )

View File

@ -4,7 +4,7 @@ import dataclasses
from typing import List, Optional from typing import List, Optional
from reflex.components.component import NoSSRComponent from reflex.components.component import NoSSRComponent
from reflex.event import EventHandler, identity_event from reflex.event import EventHandler, passthrough_event_spec
from reflex.utils.imports import ImportDict from reflex.utils.imports import ImportDict
from reflex.vars.base import LiteralVar, Var from reflex.vars.base import LiteralVar, Var
@ -96,7 +96,7 @@ class Moment(NoSSRComponent):
locale: Var[str] locale: Var[str]
# Fires when the date changes. # Fires when the date changes.
on_change: EventHandler[identity_event(str)] on_change: EventHandler[passthrough_event_spec(str)]
def add_imports(self) -> ImportDict: def add_imports(self) -> ImportDict:
"""Add the imports for the Moment component. """Add the imports for the Moment component.

View File

@ -2,7 +2,7 @@
from typing import Any, Literal, Optional, Union from typing import Any, Literal, Optional, Union
from reflex.event import EventHandler, empty_event from reflex.event import EventHandler, no_args_event_spec
from reflex.utils import types from reflex.utils import types
from reflex.vars.base import Var from reflex.vars.base import Var
@ -56,10 +56,10 @@ class Image(NextComponent):
blurDataURL: Var[str] blurDataURL: Var[str]
# Fires when the image has loaded. # Fires when the image has loaded.
on_load: EventHandler[empty_event] on_load: EventHandler[no_args_event_spec]
# Fires when the image has an error. # Fires when the image has an error.
on_error: EventHandler[empty_event] on_error: EventHandler[no_args_event_spec]
@classmethod @classmethod
def create( def create(

View File

@ -10,7 +10,7 @@ from reflex.components.component import Component, ComponentNamespace
from reflex.components.radix.primitives.base import RadixPrimitiveComponent from reflex.components.radix.primitives.base import RadixPrimitiveComponent
from reflex.components.radix.themes.base import Theme from reflex.components.radix.themes.base import Theme
from reflex.components.radix.themes.layout.flex import Flex from reflex.components.radix.themes.layout.flex import Flex
from reflex.event import EventHandler, empty_event, identity_event from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
from reflex.utils import console from reflex.utils import console
from reflex.vars.base import Var from reflex.vars.base import Var
@ -40,7 +40,7 @@ class DrawerRoot(DrawerComponent):
open: Var[bool] open: Var[bool]
# Fires when the drawer is opened or closed. # Fires when the drawer is opened or closed.
on_open_change: EventHandler[identity_event(bool)] on_open_change: EventHandler[passthrough_event_spec(bool)]
# When `False`, it allows interaction with elements outside of the drawer without closing it. Defaults to `True`. # When `False`, it allows interaction with elements outside of the drawer without closing it. Defaults to `True`.
modal: Var[bool] modal: Var[bool]
@ -49,7 +49,7 @@ class DrawerRoot(DrawerComponent):
direction: Var[LiteralDirectionType] direction: Var[LiteralDirectionType]
# Gets triggered after the open or close animation ends, it receives an open argument with the open state of the drawer by the time the function was triggered. # Gets triggered after the open or close animation ends, it receives an open argument with the open state of the drawer by the time the function was triggered.
on_animation_end: EventHandler[identity_event(bool)] on_animation_end: EventHandler[passthrough_event_spec(bool)]
# When `False`, dragging, clicking outside, pressing esc, etc. will not close the drawer. Use this in combination with the open prop, otherwise you won't be able to open/close the drawer. # When `False`, dragging, clicking outside, pressing esc, etc. will not close the drawer. Use this in combination with the open prop, otherwise you won't be able to open/close the drawer.
dismissible: Var[bool] dismissible: Var[bool]
@ -141,19 +141,19 @@ class DrawerContent(DrawerComponent):
return {"css": base_style} return {"css": base_style}
# Fired when the drawer content is opened. Deprecated. # Fired when the drawer content is opened. Deprecated.
on_open_auto_focus: EventHandler[empty_event] on_open_auto_focus: EventHandler[no_args_event_spec]
# Fired when the drawer content is closed. Deprecated. # Fired when the drawer content is closed. Deprecated.
on_close_auto_focus: EventHandler[empty_event] on_close_auto_focus: EventHandler[no_args_event_spec]
# Fired when the escape key is pressed. Deprecated. # Fired when the escape key is pressed. Deprecated.
on_escape_key_down: EventHandler[empty_event] on_escape_key_down: EventHandler[no_args_event_spec]
# Fired when the pointer is down outside the drawer content. Deprecated. # Fired when the pointer is down outside the drawer content. Deprecated.
on_pointer_down_outside: EventHandler[empty_event] on_pointer_down_outside: EventHandler[no_args_event_spec]
# Fired when interacting outside the drawer content. Deprecated. # Fired when interacting outside the drawer content. Deprecated.
on_interact_outside: EventHandler[empty_event] on_interact_outside: EventHandler[no_args_event_spec]
@classmethod @classmethod
def create(cls, *children, **props): def create(cls, *children, **props):

View File

@ -8,7 +8,7 @@ from reflex.components.component import ComponentNamespace
from reflex.components.core.debounce import DebounceInput from reflex.components.core.debounce import DebounceInput
from reflex.components.el.elements.forms import Form as HTMLForm from reflex.components.el.elements.forms import Form as HTMLForm
from reflex.components.radix.themes.components.text_field import TextFieldRoot from reflex.components.radix.themes.components.text_field import TextFieldRoot
from reflex.event import EventHandler, empty_event from reflex.event import EventHandler, no_args_event_spec
from reflex.vars.base import Var from reflex.vars.base import Var
from .base import RadixPrimitiveComponentWithClassName from .base import RadixPrimitiveComponentWithClassName
@ -28,7 +28,7 @@ class FormRoot(FormComponent, HTMLForm):
alias = "RadixFormRoot" alias = "RadixFormRoot"
# Fired when the errors are cleared. # Fired when the errors are cleared.
on_clear_server_errors: EventHandler[empty_event] on_clear_server_errors: EventHandler[no_args_event_spec]
def add_style(self) -> dict[str, Any] | None: def add_style(self) -> dict[str, Any] | None:
"""Add style to the component. """Add style to the component.

View File

@ -5,7 +5,7 @@ from typing import Literal
from reflex.components.component import ComponentNamespace from reflex.components.component import ComponentNamespace
from reflex.components.core.breakpoints import Responsive from reflex.components.core.breakpoints import Responsive
from reflex.components.el import elements from reflex.components.el import elements
from reflex.event import EventHandler, empty_event, identity_event from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
from reflex.vars.base import Var from reflex.vars.base import Var
from ..base import RadixThemesComponent, RadixThemesTriggerComponent from ..base import RadixThemesComponent, RadixThemesTriggerComponent
@ -22,7 +22,7 @@ class AlertDialogRoot(RadixThemesComponent):
open: Var[bool] open: Var[bool]
# Fired when the open state changes. # Fired when the open state changes.
on_open_change: EventHandler[identity_event(bool)] on_open_change: EventHandler[passthrough_event_spec(bool)]
# The open state of the dialog when it is initially rendered. Use when you do not need to control its open state. # The open state of the dialog when it is initially rendered. Use when you do not need to control its open state.
default_open: Var[bool] default_open: Var[bool]
@ -46,13 +46,13 @@ class AlertDialogContent(elements.Div, RadixThemesComponent):
force_mount: Var[bool] force_mount: Var[bool]
# Fired when the dialog is opened. # Fired when the dialog is opened.
on_open_auto_focus: EventHandler[empty_event] on_open_auto_focus: EventHandler[no_args_event_spec]
# Fired when the dialog is closed. # Fired when the dialog is closed.
on_close_auto_focus: EventHandler[empty_event] on_close_auto_focus: EventHandler[no_args_event_spec]
# Fired when the escape key is pressed. # Fired when the escape key is pressed.
on_escape_key_down: EventHandler[empty_event] on_escape_key_down: EventHandler[no_args_event_spec]
class AlertDialogTitle(RadixThemesComponent): class AlertDialogTitle(RadixThemesComponent):

View File

@ -6,7 +6,7 @@ from reflex.components.component import Component, ComponentNamespace
from reflex.components.core.breakpoints import Responsive from reflex.components.core.breakpoints import Responsive
from reflex.components.radix.themes.layout.flex import Flex from reflex.components.radix.themes.layout.flex import Flex
from reflex.components.radix.themes.typography.text import Text from reflex.components.radix.themes.typography.text import Text
from reflex.event import EventHandler, identity_event from reflex.event import EventHandler, passthrough_event_spec
from reflex.vars.base import LiteralVar, Var from reflex.vars.base import LiteralVar, Var
from ..base import ( from ..base import (
@ -61,7 +61,7 @@ class Checkbox(RadixThemesComponent):
_rename_props = {"onChange": "onCheckedChange"} _rename_props = {"onChange": "onCheckedChange"}
# Fired when the checkbox is checked or unchecked. # Fired when the checkbox is checked or unchecked.
on_change: EventHandler[identity_event(bool)] on_change: EventHandler[passthrough_event_spec(bool)]
class HighLevelCheckbox(RadixThemesComponent): class HighLevelCheckbox(RadixThemesComponent):
@ -112,7 +112,7 @@ class HighLevelCheckbox(RadixThemesComponent):
_rename_props = {"onChange": "onCheckedChange"} _rename_props = {"onChange": "onCheckedChange"}
# Fired when the checkbox is checked or unchecked. # Fired when the checkbox is checked or unchecked.
on_change: EventHandler[identity_event(bool)] on_change: EventHandler[passthrough_event_spec(bool)]
@classmethod @classmethod
def create(cls, text: Var[str] = LiteralVar.create(""), **props) -> Component: def create(cls, text: Var[str] = LiteralVar.create(""), **props) -> Component:

View File

@ -4,7 +4,7 @@ from typing import Dict, List, Literal, Union
from reflex.components.component import ComponentNamespace from reflex.components.component import ComponentNamespace
from reflex.components.core.breakpoints import Responsive from reflex.components.core.breakpoints import Responsive
from reflex.event import EventHandler, empty_event, identity_event from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
from reflex.vars.base import Var from reflex.vars.base import Var
from ..base import ( from ..base import (
@ -39,7 +39,7 @@ class ContextMenuRoot(RadixThemesComponent):
_invalid_children: List[str] = ["ContextMenuItem"] _invalid_children: List[str] = ["ContextMenuItem"]
# Fired when the open state changes. # Fired when the open state changes.
on_open_change: EventHandler[identity_event(bool)] on_open_change: EventHandler[passthrough_event_spec(bool)]
# The reading direction of submenus when applicable. If omitted, inherits globally from DirectionProvider or assumes LTR (left-to-right) reading mode. # The reading direction of submenus when applicable. If omitted, inherits globally from DirectionProvider or assumes LTR (left-to-right) reading mode.
dir: Var[LiteralDirType] dir: Var[LiteralDirType]
@ -109,19 +109,19 @@ class ContextMenuContent(RadixThemesComponent):
hide_when_detached: Var[bool] hide_when_detached: Var[bool]
# Fired when focus moves back after closing. # Fired when focus moves back after closing.
on_close_auto_focus: EventHandler[empty_event] on_close_auto_focus: EventHandler[no_args_event_spec]
# Fired when the escape key is pressed. # Fired when the escape key is pressed.
on_escape_key_down: EventHandler[empty_event] on_escape_key_down: EventHandler[no_args_event_spec]
# Fired when a pointer down event happens outside the context menu. # Fired when a pointer down event happens outside the context menu.
on_pointer_down_outside: EventHandler[empty_event] on_pointer_down_outside: EventHandler[no_args_event_spec]
# Fired when focus moves outside the context menu. # Fired when focus moves outside the context menu.
on_focus_outside: EventHandler[empty_event] on_focus_outside: EventHandler[no_args_event_spec]
# Fired when the pointer interacts outside the context menu. # Fired when the pointer interacts outside the context menu.
on_interact_outside: EventHandler[empty_event] on_interact_outside: EventHandler[no_args_event_spec]
class ContextMenuSub(RadixThemesComponent): class ContextMenuSub(RadixThemesComponent):
@ -136,7 +136,7 @@ class ContextMenuSub(RadixThemesComponent):
default_open: Var[bool] default_open: Var[bool]
# Fired when the open state changes. # Fired when the open state changes.
on_open_change: EventHandler[identity_event(bool)] on_open_change: EventHandler[passthrough_event_spec(bool)]
class ContextMenuSubTrigger(RadixThemesComponent): class ContextMenuSubTrigger(RadixThemesComponent):
@ -191,16 +191,16 @@ class ContextMenuSubContent(RadixThemesComponent):
_valid_parents: List[str] = ["ContextMenuSub"] _valid_parents: List[str] = ["ContextMenuSub"]
# Fired when the escape key is pressed. # Fired when the escape key is pressed.
on_escape_key_down: EventHandler[empty_event] on_escape_key_down: EventHandler[no_args_event_spec]
# Fired when a pointer down event happens outside the context menu. # Fired when a pointer down event happens outside the context menu.
on_pointer_down_outside: EventHandler[empty_event] on_pointer_down_outside: EventHandler[no_args_event_spec]
# Fired when focus moves outside the context menu. # Fired when focus moves outside the context menu.
on_focus_outside: EventHandler[empty_event] on_focus_outside: EventHandler[no_args_event_spec]
# Fired when interacting outside the context menu. # Fired when interacting outside the context menu.
on_interact_outside: EventHandler[empty_event] on_interact_outside: EventHandler[no_args_event_spec]
class ContextMenuItem(RadixThemesComponent): class ContextMenuItem(RadixThemesComponent):
@ -226,7 +226,7 @@ class ContextMenuItem(RadixThemesComponent):
_valid_parents: List[str] = ["ContextMenuContent", "ContextMenuSubContent"] _valid_parents: List[str] = ["ContextMenuContent", "ContextMenuSubContent"]
# Fired when the item is selected. # Fired when the item is selected.
on_select: EventHandler[empty_event] on_select: EventHandler[no_args_event_spec]
class ContextMenuSeparator(RadixThemesComponent): class ContextMenuSeparator(RadixThemesComponent):

View File

@ -5,7 +5,7 @@ from typing import Literal
from reflex.components.component import ComponentNamespace from reflex.components.component import ComponentNamespace
from reflex.components.core.breakpoints import Responsive from reflex.components.core.breakpoints import Responsive
from reflex.components.el import elements from reflex.components.el import elements
from reflex.event import EventHandler, empty_event, identity_event from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
from reflex.vars.base import Var from reflex.vars.base import Var
from ..base import ( from ..base import (
@ -23,7 +23,7 @@ class DialogRoot(RadixThemesComponent):
open: Var[bool] open: Var[bool]
# Fired when the open state changes. # Fired when the open state changes.
on_open_change: EventHandler[identity_event(bool)] on_open_change: EventHandler[passthrough_event_spec(bool)]
# The open state of the dialog when it is initially rendered. Use when you do not need to control its open state. # The open state of the dialog when it is initially rendered. Use when you do not need to control its open state.
default_open: Var[bool] default_open: Var[bool]
@ -50,19 +50,19 @@ class DialogContent(elements.Div, RadixThemesComponent):
size: Var[Responsive[Literal["1", "2", "3", "4"]]] size: Var[Responsive[Literal["1", "2", "3", "4"]]]
# Fired when the dialog is opened. # Fired when the dialog is opened.
on_open_auto_focus: EventHandler[empty_event] on_open_auto_focus: EventHandler[no_args_event_spec]
# Fired when the dialog is closed. # Fired when the dialog is closed.
on_close_auto_focus: EventHandler[empty_event] on_close_auto_focus: EventHandler[no_args_event_spec]
# Fired when the escape key is pressed. # Fired when the escape key is pressed.
on_escape_key_down: EventHandler[empty_event] on_escape_key_down: EventHandler[no_args_event_spec]
# Fired when the pointer is down outside the dialog. # Fired when the pointer is down outside the dialog.
on_pointer_down_outside: EventHandler[empty_event] on_pointer_down_outside: EventHandler[no_args_event_spec]
# Fired when the pointer interacts outside the dialog. # Fired when the pointer interacts outside the dialog.
on_interact_outside: EventHandler[empty_event] on_interact_outside: EventHandler[no_args_event_spec]
class DialogDescription(RadixThemesComponent): class DialogDescription(RadixThemesComponent):

View File

@ -4,7 +4,7 @@ from typing import Dict, List, Literal, Union
from reflex.components.component import ComponentNamespace from reflex.components.component import ComponentNamespace
from reflex.components.core.breakpoints import Responsive from reflex.components.core.breakpoints import Responsive
from reflex.event import EventHandler, empty_event, identity_event from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
from reflex.vars.base import Var from reflex.vars.base import Var
from ..base import ( from ..base import (
@ -49,7 +49,7 @@ class DropdownMenuRoot(RadixThemesComponent):
_invalid_children: List[str] = ["DropdownMenuItem"] _invalid_children: List[str] = ["DropdownMenuItem"]
# Fired when the open state changes. # Fired when the open state changes.
on_open_change: EventHandler[identity_event(bool)] on_open_change: EventHandler[passthrough_event_spec(bool)]
class DropdownMenuTrigger(RadixThemesTriggerComponent): class DropdownMenuTrigger(RadixThemesTriggerComponent):
@ -116,19 +116,19 @@ class DropdownMenuContent(RadixThemesComponent):
hide_when_detached: Var[bool] hide_when_detached: Var[bool]
# Fired when the dialog is closed. # Fired when the dialog is closed.
on_close_auto_focus: EventHandler[empty_event] on_close_auto_focus: EventHandler[no_args_event_spec]
# Fired when the escape key is pressed. # Fired when the escape key is pressed.
on_escape_key_down: EventHandler[empty_event] on_escape_key_down: EventHandler[no_args_event_spec]
# Fired when the pointer is down outside the dialog. # Fired when the pointer is down outside the dialog.
on_pointer_down_outside: EventHandler[empty_event] on_pointer_down_outside: EventHandler[no_args_event_spec]
# Fired when focus moves outside the dialog. # Fired when focus moves outside the dialog.
on_focus_outside: EventHandler[empty_event] on_focus_outside: EventHandler[no_args_event_spec]
# Fired when the pointer interacts outside the dialog. # Fired when the pointer interacts outside the dialog.
on_interact_outside: EventHandler[empty_event] on_interact_outside: EventHandler[no_args_event_spec]
class DropdownMenuSubTrigger(RadixThemesTriggerComponent): class DropdownMenuSubTrigger(RadixThemesTriggerComponent):
@ -160,7 +160,7 @@ class DropdownMenuSub(RadixThemesComponent):
default_open: Var[bool] default_open: Var[bool]
# Fired when the open state changes. # Fired when the open state changes.
on_open_change: EventHandler[identity_event(bool)] on_open_change: EventHandler[passthrough_event_spec(bool)]
class DropdownMenuSubContent(RadixThemesComponent): class DropdownMenuSubContent(RadixThemesComponent):
@ -198,16 +198,16 @@ class DropdownMenuSubContent(RadixThemesComponent):
_valid_parents: List[str] = ["DropdownMenuSub"] _valid_parents: List[str] = ["DropdownMenuSub"]
# Fired when the escape key is pressed. # Fired when the escape key is pressed.
on_escape_key_down: EventHandler[empty_event] on_escape_key_down: EventHandler[no_args_event_spec]
# Fired when the pointer is down outside the dialog. # Fired when the pointer is down outside the dialog.
on_pointer_down_outside: EventHandler[empty_event] on_pointer_down_outside: EventHandler[no_args_event_spec]
# Fired when focus moves outside the dialog. # Fired when focus moves outside the dialog.
on_focus_outside: EventHandler[empty_event] on_focus_outside: EventHandler[no_args_event_spec]
# Fired when the pointer interacts outside the dialog. # Fired when the pointer interacts outside the dialog.
on_interact_outside: EventHandler[empty_event] on_interact_outside: EventHandler[no_args_event_spec]
class DropdownMenuItem(RadixThemesComponent): class DropdownMenuItem(RadixThemesComponent):
@ -233,7 +233,7 @@ class DropdownMenuItem(RadixThemesComponent):
_valid_parents: List[str] = ["DropdownMenuContent", "DropdownMenuSubContent"] _valid_parents: List[str] = ["DropdownMenuContent", "DropdownMenuSubContent"]
# Fired when the item is selected. # Fired when the item is selected.
on_select: EventHandler[empty_event] on_select: EventHandler[no_args_event_spec]
class DropdownMenuSeparator(RadixThemesComponent): class DropdownMenuSeparator(RadixThemesComponent):

View File

@ -5,7 +5,7 @@ from typing import Dict, Literal, Union
from reflex.components.component import ComponentNamespace from reflex.components.component import ComponentNamespace
from reflex.components.core.breakpoints import Responsive from reflex.components.core.breakpoints import Responsive
from reflex.components.el import elements from reflex.components.el import elements
from reflex.event import EventHandler, identity_event from reflex.event import EventHandler, passthrough_event_spec
from reflex.vars.base import Var from reflex.vars.base import Var
from ..base import ( from ..base import (
@ -32,7 +32,7 @@ class HoverCardRoot(RadixThemesComponent):
close_delay: Var[int] close_delay: Var[int]
# Fired when the open state changes. # Fired when the open state changes.
on_open_change: EventHandler[identity_event(bool)] on_open_change: EventHandler[passthrough_event_spec(bool)]
class HoverCardTrigger(RadixThemesTriggerComponent): class HoverCardTrigger(RadixThemesTriggerComponent):

View File

@ -5,7 +5,7 @@ from typing import Dict, Literal, Union
from reflex.components.component import ComponentNamespace from reflex.components.component import ComponentNamespace
from reflex.components.core.breakpoints import Responsive from reflex.components.core.breakpoints import Responsive
from reflex.components.el import elements from reflex.components.el import elements
from reflex.event import EventHandler, empty_event, identity_event from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
from reflex.vars.base import Var from reflex.vars.base import Var
from ..base import ( from ..base import (
@ -26,7 +26,7 @@ class PopoverRoot(RadixThemesComponent):
modal: Var[bool] modal: Var[bool]
# Fired when the open state changes. # Fired when the open state changes.
on_open_change: EventHandler[identity_event(bool)] on_open_change: EventHandler[passthrough_event_spec(bool)]
# The open state of the popover when it is initially rendered. Use when you do not need to control its open state. # The open state of the popover when it is initially rendered. Use when you do not need to control its open state.
default_open: Var[bool] default_open: Var[bool]
@ -71,22 +71,22 @@ class PopoverContent(elements.Div, RadixThemesComponent):
hide_when_detached: Var[bool] hide_when_detached: Var[bool]
# Fired when the dialog is opened. # Fired when the dialog is opened.
on_open_auto_focus: EventHandler[empty_event] on_open_auto_focus: EventHandler[no_args_event_spec]
# Fired when the dialog is closed. # Fired when the dialog is closed.
on_close_auto_focus: EventHandler[empty_event] on_close_auto_focus: EventHandler[no_args_event_spec]
# Fired when the escape key is pressed. # Fired when the escape key is pressed.
on_escape_key_down: EventHandler[empty_event] on_escape_key_down: EventHandler[no_args_event_spec]
# Fired when the pointer is down outside the dialog. # Fired when the pointer is down outside the dialog.
on_pointer_down_outside: EventHandler[empty_event] on_pointer_down_outside: EventHandler[no_args_event_spec]
# Fired when focus moves outside the dialog. # Fired when focus moves outside the dialog.
on_focus_outside: EventHandler[empty_event] on_focus_outside: EventHandler[no_args_event_spec]
# Fired when the pointer interacts outside the dialog. # Fired when the pointer interacts outside the dialog.
on_interact_outside: EventHandler[empty_event] on_interact_outside: EventHandler[no_args_event_spec]
class PopoverClose(RadixThemesTriggerComponent): class PopoverClose(RadixThemesTriggerComponent):

View File

@ -4,7 +4,7 @@ from types import SimpleNamespace
from typing import Literal, Union from typing import Literal, Union
from reflex.components.core.breakpoints import Responsive from reflex.components.core.breakpoints import Responsive
from reflex.event import EventHandler, identity_event from reflex.event import EventHandler, passthrough_event_spec
from reflex.vars.base import Var from reflex.vars.base import Var
from ..base import LiteralAccentColor, RadixThemesComponent from ..base import LiteralAccentColor, RadixThemesComponent
@ -65,7 +65,7 @@ class RadioCardsRoot(RadixThemesComponent):
loop: Var[bool] loop: Var[bool]
# Event handler called when the value changes. # Event handler called when the value changes.
on_value_change: EventHandler[identity_event(str)] on_value_change: EventHandler[passthrough_event_spec(str)]
class RadioCardsItem(RadixThemesComponent): class RadioCardsItem(RadixThemesComponent):

View File

@ -9,7 +9,7 @@ from reflex.components.component import Component, ComponentNamespace
from reflex.components.core.breakpoints import Responsive from reflex.components.core.breakpoints import Responsive
from reflex.components.radix.themes.layout.flex import Flex from reflex.components.radix.themes.layout.flex import Flex
from reflex.components.radix.themes.typography.text import Text from reflex.components.radix.themes.typography.text import Text
from reflex.event import EventHandler, identity_event from reflex.event import EventHandler, passthrough_event_spec
from reflex.utils import types from reflex.utils import types
from reflex.vars.base import LiteralVar, Var from reflex.vars.base import LiteralVar, Var
from reflex.vars.sequence import StringVar from reflex.vars.sequence import StringVar
@ -59,7 +59,7 @@ class RadioGroupRoot(RadixThemesComponent):
_rename_props = {"onChange": "onValueChange"} _rename_props = {"onChange": "onValueChange"}
# Fired when the value of the radio group changes. # Fired when the value of the radio group changes.
on_change: EventHandler[identity_event(str)] on_change: EventHandler[passthrough_event_spec(str)]
class RadioGroupItem(RadixThemesComponent): class RadioGroupItem(RadixThemesComponent):

View File

@ -5,7 +5,7 @@ from typing import List, Literal, Union
import reflex as rx import reflex as rx
from reflex.components.component import Component, ComponentNamespace from reflex.components.component import Component, ComponentNamespace
from reflex.components.core.breakpoints import Responsive from reflex.components.core.breakpoints import Responsive
from reflex.event import empty_event, identity_event from reflex.event import no_args_event_spec, passthrough_event_spec
from reflex.vars.base import Var from reflex.vars.base import Var
from ..base import ( from ..base import (
@ -48,10 +48,10 @@ class SelectRoot(RadixThemesComponent):
_rename_props = {"onChange": "onValueChange"} _rename_props = {"onChange": "onValueChange"}
# Fired when the value of the select changes. # Fired when the value of the select changes.
on_change: rx.EventHandler[identity_event(str)] on_change: rx.EventHandler[passthrough_event_spec(str)]
# Fired when the select is opened or closed. # Fired when the select is opened or closed.
on_open_change: rx.EventHandler[identity_event(bool)] on_open_change: rx.EventHandler[passthrough_event_spec(bool)]
class SelectTrigger(RadixThemesComponent): class SelectTrigger(RadixThemesComponent):
@ -104,13 +104,13 @@ class SelectContent(RadixThemesComponent):
align_offset: Var[int] align_offset: Var[int]
# Fired when the select content is closed. # Fired when the select content is closed.
on_close_auto_focus: rx.EventHandler[empty_event] on_close_auto_focus: rx.EventHandler[no_args_event_spec]
# Fired when the escape key is pressed. # Fired when the escape key is pressed.
on_escape_key_down: rx.EventHandler[empty_event] on_escape_key_down: rx.EventHandler[no_args_event_spec]
# Fired when a pointer down event happens outside the select content. # Fired when a pointer down event happens outside the select content.
on_pointer_down_outside: rx.EventHandler[empty_event] on_pointer_down_outside: rx.EventHandler[no_args_event_spec]
class SelectGroup(RadixThemesComponent): class SelectGroup(RadixThemesComponent):

View File

@ -6,7 +6,7 @@ from typing import List, Literal, Optional, Union
from reflex.components.component import Component from reflex.components.component import Component
from reflex.components.core.breakpoints import Responsive from reflex.components.core.breakpoints import Responsive
from reflex.event import EventHandler, identity_event from reflex.event import EventHandler, passthrough_event_spec
from reflex.vars.base import Var from reflex.vars.base import Var
from ..base import ( from ..base import (
@ -15,9 +15,9 @@ from ..base import (
) )
on_value_event_spec = ( on_value_event_spec = (
identity_event(list[Union[int, float]]), passthrough_event_spec(list[Union[int, float]]),
identity_event(list[int]), passthrough_event_spec(list[int]),
identity_event(list[float]), passthrough_event_spec(list[float]),
) )

View File

@ -6,16 +6,16 @@
from typing import Any, Dict, List, Literal, Optional, Union, overload from typing import Any, Dict, List, Literal, Optional, Union, overload
from reflex.components.core.breakpoints import Breakpoints from reflex.components.core.breakpoints import Breakpoints
from reflex.event import EventType, identity_event from reflex.event import EventType, passthrough_event_spec
from reflex.style import Style from reflex.style import Style
from reflex.vars.base import Var from reflex.vars.base import Var
from ..base import RadixThemesComponent from ..base import RadixThemesComponent
on_value_event_spec = ( on_value_event_spec = (
identity_event(list[Union[int, float]]), passthrough_event_spec(list[Union[int, float]]),
identity_event(list[int]), passthrough_event_spec(list[int]),
identity_event(list[float]), passthrough_event_spec(list[float]),
) )
class Slider(RadixThemesComponent): class Slider(RadixThemesComponent):

View File

@ -3,7 +3,7 @@
from typing import Literal from typing import Literal
from reflex.components.core.breakpoints import Responsive from reflex.components.core.breakpoints import Responsive
from reflex.event import EventHandler, identity_event from reflex.event import EventHandler, passthrough_event_spec
from reflex.vars.base import Var from reflex.vars.base import Var
from ..base import ( from ..base import (
@ -59,7 +59,7 @@ class Switch(RadixThemesComponent):
_rename_props = {"onChange": "onCheckedChange"} _rename_props = {"onChange": "onCheckedChange"}
# Fired when the value of the switch changes # Fired when the value of the switch changes
on_change: EventHandler[identity_event(bool)] on_change: EventHandler[passthrough_event_spec(bool)]
switch = Switch.create switch = Switch.create

View File

@ -7,7 +7,7 @@ from typing import Any, Dict, List, Literal
from reflex.components.component import Component, ComponentNamespace from reflex.components.component import Component, ComponentNamespace
from reflex.components.core.breakpoints import Responsive from reflex.components.core.breakpoints import Responsive
from reflex.components.core.colors import color from reflex.components.core.colors import color
from reflex.event import EventHandler, identity_event from reflex.event import EventHandler, passthrough_event_spec
from reflex.vars.base import Var from reflex.vars.base import Var
from ..base import ( from ..base import (
@ -42,7 +42,7 @@ class TabsRoot(RadixThemesComponent):
_rename_props = {"onChange": "onValueChange"} _rename_props = {"onChange": "onValueChange"}
# Fired when the value of the tabs changes. # Fired when the value of the tabs changes.
on_change: EventHandler[identity_event(str)] on_change: EventHandler[passthrough_event_spec(str)]
def add_style(self) -> Dict[str, Any] | None: def add_style(self) -> Dict[str, Any] | None:
"""Add style for the component. """Add style for the component.

View File

@ -3,7 +3,7 @@
from typing import Dict, Literal, Union from typing import Dict, Literal, Union
from reflex.components.component import Component from reflex.components.component import Component
from reflex.event import EventHandler, empty_event, identity_event from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
from reflex.utils import format from reflex.utils import format
from reflex.vars.base import Var from reflex.vars.base import Var
@ -85,13 +85,13 @@ class Tooltip(RadixThemesComponent):
aria_label: Var[str] aria_label: Var[str]
# Fired when the open state changes. # Fired when the open state changes.
on_open_change: EventHandler[identity_event(bool)] on_open_change: EventHandler[passthrough_event_spec(bool)]
# Fired when the escape key is pressed. # Fired when the escape key is pressed.
on_escape_key_down: EventHandler[empty_event] on_escape_key_down: EventHandler[no_args_event_spec]
# Fired when the pointer is down outside the tooltip. # Fired when the pointer is down outside the tooltip.
on_pointer_down_outside: EventHandler[empty_event] on_pointer_down_outside: EventHandler[no_args_event_spec]
@classmethod @classmethod
def create(cls, *children, **props) -> Component: def create(cls, *children, **props) -> Component:

View File

@ -5,7 +5,7 @@ from __future__ import annotations
from typing_extensions import TypedDict from typing_extensions import TypedDict
from reflex.components.component import NoSSRComponent from reflex.components.component import NoSSRComponent
from reflex.event import EventHandler, empty_event, identity_event from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
from reflex.vars.base import Var from reflex.vars.base import Var
@ -57,49 +57,49 @@ class ReactPlayer(NoSSRComponent):
height: Var[str] height: Var[str]
# Called when media is loaded and ready to play. If playing is set to true, media will play immediately. # Called when media is loaded and ready to play. If playing is set to true, media will play immediately.
on_ready: EventHandler[empty_event] on_ready: EventHandler[no_args_event_spec]
# Called when media starts playing. # Called when media starts playing.
on_start: EventHandler[empty_event] on_start: EventHandler[no_args_event_spec]
# Called when media starts or resumes playing after pausing or buffering. # Called when media starts or resumes playing after pausing or buffering.
on_play: EventHandler[empty_event] on_play: EventHandler[no_args_event_spec]
# Callback containing played and loaded progress as a fraction, and playedSeconds and loadedSeconds in seconds. eg { played: 0.12, playedSeconds: 11.3, loaded: 0.34, loadedSeconds: 16.7 } # Callback containing played and loaded progress as a fraction, and playedSeconds and loadedSeconds in seconds. eg { played: 0.12, playedSeconds: 11.3, loaded: 0.34, loadedSeconds: 16.7 }
on_progress: EventHandler[identity_event(Progress)] on_progress: EventHandler[passthrough_event_spec(Progress)]
# Callback containing duration of the media, in seconds. # Callback containing duration of the media, in seconds.
on_duration: EventHandler[identity_event(float)] on_duration: EventHandler[passthrough_event_spec(float)]
# Called when media is paused. # Called when media is paused.
on_pause: EventHandler[empty_event] on_pause: EventHandler[no_args_event_spec]
# Called when media starts buffering. # Called when media starts buffering.
on_buffer: EventHandler[empty_event] on_buffer: EventHandler[no_args_event_spec]
# Called when media has finished buffering. Works for files, YouTube and Facebook. # Called when media has finished buffering. Works for files, YouTube and Facebook.
on_buffer_end: EventHandler[empty_event] on_buffer_end: EventHandler[no_args_event_spec]
# Called when media seeks with seconds parameter. # Called when media seeks with seconds parameter.
on_seek: EventHandler[identity_event(float)] on_seek: EventHandler[passthrough_event_spec(float)]
# Called when playback rate of the player changed. Only supported by YouTube, Vimeo (if enabled), Wistia, and file paths. # Called when playback rate of the player changed. Only supported by YouTube, Vimeo (if enabled), Wistia, and file paths.
on_playback_rate_change: EventHandler[empty_event] on_playback_rate_change: EventHandler[no_args_event_spec]
# Called when playback quality of the player changed. Only supported by YouTube (if enabled). # Called when playback quality of the player changed. Only supported by YouTube (if enabled).
on_playback_quality_change: EventHandler[empty_event] on_playback_quality_change: EventHandler[no_args_event_spec]
# Called when media finishes playing. Does not fire when loop is set to true. # Called when media finishes playing. Does not fire when loop is set to true.
on_ended: EventHandler[empty_event] on_ended: EventHandler[no_args_event_spec]
# Called when an error occurs whilst attempting to play media. # Called when an error occurs whilst attempting to play media.
on_error: EventHandler[empty_event] on_error: EventHandler[no_args_event_spec]
# Called when user clicks the light mode preview. # Called when user clicks the light mode preview.
on_click_preview: EventHandler[empty_event] on_click_preview: EventHandler[no_args_event_spec]
# Called when picture-in-picture mode is enabled. # Called when picture-in-picture mode is enabled.
on_enable_pip: EventHandler[empty_event] on_enable_pip: EventHandler[no_args_event_spec]
# Called when picture-in-picture mode is disabled. # Called when picture-in-picture mode is disabled.
on_disable_pip: EventHandler[empty_event] on_disable_pip: EventHandler[no_args_event_spec]

View File

@ -6,7 +6,7 @@ from typing import Any, Dict, List, Union
from reflex.constants import EventTriggers from reflex.constants import EventTriggers
from reflex.constants.colors import Color from reflex.constants.colors import Color
from reflex.event import EventHandler, empty_event from reflex.event import EventHandler, no_args_event_spec
from reflex.vars.base import LiteralVar, Var from reflex.vars.base import LiteralVar, Var
from .recharts import ( from .recharts import (
@ -109,25 +109,25 @@ class Axis(Recharts):
text_anchor: Var[LiteralTextAnchor] text_anchor: Var[LiteralTextAnchor]
# The customized event handler of click on the ticks of this axis # The customized event handler of click on the ticks of this axis
on_click: EventHandler[empty_event] on_click: EventHandler[no_args_event_spec]
# The customized event handler of mousedown on the ticks of this axis # The customized event handler of mousedown on the ticks of this axis
on_mouse_down: EventHandler[empty_event] on_mouse_down: EventHandler[no_args_event_spec]
# The customized event handler of mouseup on the ticks of this axis # The customized event handler of mouseup on the ticks of this axis
on_mouse_up: EventHandler[empty_event] on_mouse_up: EventHandler[no_args_event_spec]
# The customized event handler of mousemove on the ticks of this axis # The customized event handler of mousemove on the ticks of this axis
on_mouse_move: EventHandler[empty_event] on_mouse_move: EventHandler[no_args_event_spec]
# The customized event handler of mouseout on the ticks of this axis # The customized event handler of mouseout on the ticks of this axis
on_mouse_out: EventHandler[empty_event] on_mouse_out: EventHandler[no_args_event_spec]
# The customized event handler of mouseenter on the ticks of this axis # The customized event handler of mouseenter on the ticks of this axis
on_mouse_enter: EventHandler[empty_event] on_mouse_enter: EventHandler[no_args_event_spec]
# The customized event handler of mouseleave on the ticks of this axis # The customized event handler of mouseleave on the ticks of this axis
on_mouse_leave: EventHandler[empty_event] on_mouse_leave: EventHandler[no_args_event_spec]
class XAxis(Axis): class XAxis(Axis):
@ -252,7 +252,7 @@ class Brush(Recharts):
A dict mapping the event trigger to the var that is passed to the handler. A dict mapping the event trigger to the var that is passed to the handler.
""" """
return { return {
EventTriggers.ON_CHANGE: empty_event, EventTriggers.ON_CHANGE: no_args_event_spec,
} }
@ -293,34 +293,34 @@ class Cartesian(Recharts):
name: Var[Union[str, int]] name: Var[Union[str, int]]
# The customized event handler of animation start # The customized event handler of animation start
on_animation_start: EventHandler[empty_event] on_animation_start: EventHandler[no_args_event_spec]
# The customized event handler of animation end # The customized event handler of animation end
on_animation_end: EventHandler[empty_event] on_animation_end: EventHandler[no_args_event_spec]
# The customized event handler of click on the component in this group # The customized event handler of click on the component in this group
on_click: EventHandler[empty_event] on_click: EventHandler[no_args_event_spec]
# The customized event handler of mousedown on the component in this group # The customized event handler of mousedown on the component in this group
on_mouse_down: EventHandler[empty_event] on_mouse_down: EventHandler[no_args_event_spec]
# The customized event handler of mouseup on the component in this group # The customized event handler of mouseup on the component in this group
on_mouse_up: EventHandler[empty_event] on_mouse_up: EventHandler[no_args_event_spec]
# The customized event handler of mousemove on the component in this group # The customized event handler of mousemove on the component in this group
on_mouse_move: EventHandler[empty_event] on_mouse_move: EventHandler[no_args_event_spec]
# The customized event handler of mouseover on the component in this group # The customized event handler of mouseover on the component in this group
on_mouse_over: EventHandler[empty_event] on_mouse_over: EventHandler[no_args_event_spec]
# The customized event handler of mouseout on the component in this group # The customized event handler of mouseout on the component in this group
on_mouse_out: EventHandler[empty_event] on_mouse_out: EventHandler[no_args_event_spec]
# The customized event handler of mouseenter on the component in this group # The customized event handler of mouseenter on the component in this group
on_mouse_enter: EventHandler[empty_event] on_mouse_enter: EventHandler[no_args_event_spec]
# The customized event handler of mouseleave on the component in this group # The customized event handler of mouseleave on the component in this group
on_mouse_leave: EventHandler[empty_event] on_mouse_leave: EventHandler[no_args_event_spec]
class Area(Cartesian): class Area(Cartesian):
@ -526,28 +526,28 @@ class Scatter(Recharts):
animation_easing: Var[LiteralAnimationEasing] animation_easing: Var[LiteralAnimationEasing]
# The customized event handler of click on the component in this group # The customized event handler of click on the component in this group
on_click: EventHandler[empty_event] on_click: EventHandler[no_args_event_spec]
# The customized event handler of mousedown on the component in this group # The customized event handler of mousedown on the component in this group
on_mouse_down: EventHandler[empty_event] on_mouse_down: EventHandler[no_args_event_spec]
# The customized event handler of mouseup on the component in this group # The customized event handler of mouseup on the component in this group
on_mouse_up: EventHandler[empty_event] on_mouse_up: EventHandler[no_args_event_spec]
# The customized event handler of mousemove on the component in this group # The customized event handler of mousemove on the component in this group
on_mouse_move: EventHandler[empty_event] on_mouse_move: EventHandler[no_args_event_spec]
# The customized event handler of mouseover on the component in this group # The customized event handler of mouseover on the component in this group
on_mouse_over: EventHandler[empty_event] on_mouse_over: EventHandler[no_args_event_spec]
# The customized event handler of mouseout on the component in this group # The customized event handler of mouseout on the component in this group
on_mouse_out: EventHandler[empty_event] on_mouse_out: EventHandler[no_args_event_spec]
# The customized event handler of mouseenter on the component in this group # The customized event handler of mouseenter on the component in this group
on_mouse_enter: EventHandler[empty_event] on_mouse_enter: EventHandler[no_args_event_spec]
# The customized event handler of mouseleave on the component in this group # The customized event handler of mouseleave on the component in this group
on_mouse_leave: EventHandler[empty_event] on_mouse_leave: EventHandler[no_args_event_spec]
class Funnel(Recharts): class Funnel(Recharts):
@ -591,34 +591,34 @@ class Funnel(Recharts):
_valid_children: List[str] = ["LabelList", "Cell"] _valid_children: List[str] = ["LabelList", "Cell"]
# The customized event handler of animation start # The customized event handler of animation start
on_animation_start: EventHandler[empty_event] on_animation_start: EventHandler[no_args_event_spec]
# The customized event handler of animation end # The customized event handler of animation end
on_animation_end: EventHandler[empty_event] on_animation_end: EventHandler[no_args_event_spec]
# The customized event handler of click on the component in this group # The customized event handler of click on the component in this group
on_click: EventHandler[empty_event] on_click: EventHandler[no_args_event_spec]
# The customized event handler of mousedown on the component in this group # The customized event handler of mousedown on the component in this group
on_mouse_down: EventHandler[empty_event] on_mouse_down: EventHandler[no_args_event_spec]
# The customized event handler of mouseup on the component in this group # The customized event handler of mouseup on the component in this group
on_mouse_up: EventHandler[empty_event] on_mouse_up: EventHandler[no_args_event_spec]
# The customized event handler of mousemove on the component in this group # The customized event handler of mousemove on the component in this group
on_mouse_move: EventHandler[empty_event] on_mouse_move: EventHandler[no_args_event_spec]
# The customized event handler of mouseover on the component in this group # The customized event handler of mouseover on the component in this group
on_mouse_over: EventHandler[empty_event] on_mouse_over: EventHandler[no_args_event_spec]
# The customized event handler of mouseout on the component in this group # The customized event handler of mouseout on the component in this group
on_mouse_out: EventHandler[empty_event] on_mouse_out: EventHandler[no_args_event_spec]
# The customized event handler of mouseenter on the component in this group # The customized event handler of mouseenter on the component in this group
on_mouse_enter: EventHandler[empty_event] on_mouse_enter: EventHandler[no_args_event_spec]
# The customized event handler of mouseleave on the component in this group # The customized event handler of mouseleave on the component in this group
on_mouse_leave: EventHandler[empty_event] on_mouse_leave: EventHandler[no_args_event_spec]
class ErrorBar(Recharts): class ErrorBar(Recharts):
@ -715,28 +715,28 @@ class ReferenceDot(Reference):
_valid_children: List[str] = ["Label"] _valid_children: List[str] = ["Label"]
# The customized event handler of click on the component in this chart # The customized event handler of click on the component in this chart
on_click: EventHandler[empty_event] on_click: EventHandler[no_args_event_spec]
# The customized event handler of mousedown on the component in this chart # The customized event handler of mousedown on the component in this chart
on_mouse_down: EventHandler[empty_event] on_mouse_down: EventHandler[no_args_event_spec]
# The customized event handler of mouseup on the component in this chart # The customized event handler of mouseup on the component in this chart
on_mouse_up: EventHandler[empty_event] on_mouse_up: EventHandler[no_args_event_spec]
# The customized event handler of mouseover on the component in this chart # The customized event handler of mouseover on the component in this chart
on_mouse_over: EventHandler[empty_event] on_mouse_over: EventHandler[no_args_event_spec]
# The customized event handler of mouseout on the component in this chart # The customized event handler of mouseout on the component in this chart
on_mouse_out: EventHandler[empty_event] on_mouse_out: EventHandler[no_args_event_spec]
# The customized event handler of mouseenter on the component in this chart # The customized event handler of mouseenter on the component in this chart
on_mouse_enter: EventHandler[empty_event] on_mouse_enter: EventHandler[no_args_event_spec]
# The customized event handler of mousemove on the component in this chart # The customized event handler of mousemove on the component in this chart
on_mouse_move: EventHandler[empty_event] on_mouse_move: EventHandler[no_args_event_spec]
# The customized event handler of mouseleave on the component in this chart # The customized event handler of mouseleave on the component in this chart
on_mouse_leave: EventHandler[empty_event] on_mouse_leave: EventHandler[no_args_event_spec]
class ReferenceArea(Recharts): class ReferenceArea(Recharts):

View File

@ -8,7 +8,7 @@ from reflex.components.component import Component
from reflex.components.recharts.general import ResponsiveContainer from reflex.components.recharts.general import ResponsiveContainer
from reflex.constants import EventTriggers from reflex.constants import EventTriggers
from reflex.constants.colors import Color from reflex.constants.colors import Color
from reflex.event import EventHandler, empty_event from reflex.event import EventHandler, no_args_event_spec
from reflex.vars.base import Var from reflex.vars.base import Var
from .recharts import ( from .recharts import (
@ -31,16 +31,16 @@ class ChartBase(RechartsCharts):
height: Var[Union[str, int]] = "100%" # type: ignore height: Var[Union[str, int]] = "100%" # type: ignore
# The customized event handler of click on the component in this chart # The customized event handler of click on the component in this chart
on_click: EventHandler[empty_event] on_click: EventHandler[no_args_event_spec]
# The customized event handler of mouseenter on the component in this chart # The customized event handler of mouseenter on the component in this chart
on_mouse_enter: EventHandler[empty_event] on_mouse_enter: EventHandler[no_args_event_spec]
# The customized event handler of mousemove on the component in this chart # The customized event handler of mousemove on the component in this chart
on_mouse_move: EventHandler[empty_event] on_mouse_move: EventHandler[no_args_event_spec]
# The customized event handler of mouseleave on the component in this chart # The customized event handler of mouseleave on the component in this chart
on_mouse_leave: EventHandler[empty_event] on_mouse_leave: EventHandler[no_args_event_spec]
@staticmethod @staticmethod
def _ensure_valid_dimension(name: str, value: Any) -> None: def _ensure_valid_dimension(name: str, value: Any) -> None:
@ -270,16 +270,16 @@ class PieChart(ChartBase):
] ]
# The customized event handler of mousedown on the sectors in this group # The customized event handler of mousedown on the sectors in this group
on_mouse_down: EventHandler[empty_event] on_mouse_down: EventHandler[no_args_event_spec]
# The customized event handler of mouseup on the sectors in this group # The customized event handler of mouseup on the sectors in this group
on_mouse_up: EventHandler[empty_event] on_mouse_up: EventHandler[no_args_event_spec]
# The customized event handler of mouseover on the sectors in this group # The customized event handler of mouseover on the sectors in this group
on_mouse_over: EventHandler[empty_event] on_mouse_over: EventHandler[no_args_event_spec]
# The customized event handler of mouseout on the sectors in this group # The customized event handler of mouseout on the sectors in this group
on_mouse_out: EventHandler[empty_event] on_mouse_out: EventHandler[no_args_event_spec]
class RadarChart(ChartBase): class RadarChart(ChartBase):
@ -330,9 +330,9 @@ class RadarChart(ChartBase):
A dict mapping the event trigger to the var that is passed to the handler. A dict mapping the event trigger to the var that is passed to the handler.
""" """
return { return {
EventTriggers.ON_CLICK: empty_event, EventTriggers.ON_CLICK: no_args_event_spec,
EventTriggers.ON_MOUSE_ENTER: empty_event, EventTriggers.ON_MOUSE_ENTER: no_args_event_spec,
EventTriggers.ON_MOUSE_LEAVE: empty_event, EventTriggers.ON_MOUSE_LEAVE: no_args_event_spec,
} }
@ -419,14 +419,14 @@ class ScatterChart(ChartBase):
A dict mapping the event trigger to the var that is passed to the handler. A dict mapping the event trigger to the var that is passed to the handler.
""" """
return { return {
EventTriggers.ON_CLICK: empty_event, EventTriggers.ON_CLICK: no_args_event_spec,
EventTriggers.ON_MOUSE_DOWN: empty_event, EventTriggers.ON_MOUSE_DOWN: no_args_event_spec,
EventTriggers.ON_MOUSE_UP: empty_event, EventTriggers.ON_MOUSE_UP: no_args_event_spec,
EventTriggers.ON_MOUSE_MOVE: empty_event, EventTriggers.ON_MOUSE_MOVE: no_args_event_spec,
EventTriggers.ON_MOUSE_OVER: empty_event, EventTriggers.ON_MOUSE_OVER: no_args_event_spec,
EventTriggers.ON_MOUSE_OUT: empty_event, EventTriggers.ON_MOUSE_OUT: no_args_event_spec,
EventTriggers.ON_MOUSE_ENTER: empty_event, EventTriggers.ON_MOUSE_ENTER: no_args_event_spec,
EventTriggers.ON_MOUSE_LEAVE: empty_event, EventTriggers.ON_MOUSE_LEAVE: no_args_event_spec,
} }
@ -488,10 +488,10 @@ class Treemap(RechartsCharts):
animation_easing: Var[LiteralAnimationEasing] animation_easing: Var[LiteralAnimationEasing]
# The customized event handler of animation start # The customized event handler of animation start
on_animation_start: EventHandler[empty_event] on_animation_start: EventHandler[no_args_event_spec]
# The customized event handler of animation end # The customized event handler of animation end
on_animation_end: EventHandler[empty_event] on_animation_end: EventHandler[no_args_event_spec]
@classmethod @classmethod
def create(cls, *children, **props) -> Component: def create(cls, *children, **props) -> Component:

View File

@ -6,7 +6,7 @@ from typing import Any, Dict, List, Union
from reflex.components.component import MemoizationLeaf from reflex.components.component import MemoizationLeaf
from reflex.constants.colors import Color from reflex.constants.colors import Color
from reflex.event import EventHandler, empty_event from reflex.event import EventHandler, no_args_event_spec
from reflex.vars.base import LiteralVar, Var from reflex.vars.base import LiteralVar, Var
from .recharts import ( from .recharts import (
@ -46,7 +46,7 @@ class ResponsiveContainer(Recharts, MemoizationLeaf):
debounce: Var[int] debounce: Var[int]
# If specified provides a callback providing the updated chart width and height values. # If specified provides a callback providing the updated chart width and height values.
on_resize: EventHandler[empty_event] on_resize: EventHandler[no_args_event_spec]
# Valid children components # Valid children components
_valid_children: List[str] = [ _valid_children: List[str] = [
@ -104,28 +104,28 @@ class Legend(Recharts):
margin: Var[Dict[str, Any]] margin: Var[Dict[str, Any]]
# The customized event handler of click on the items in this group # The customized event handler of click on the items in this group
on_click: EventHandler[empty_event] on_click: EventHandler[no_args_event_spec]
# The customized event handler of mousedown on the items in this group # The customized event handler of mousedown on the items in this group
on_mouse_down: EventHandler[empty_event] on_mouse_down: EventHandler[no_args_event_spec]
# The customized event handler of mouseup on the items in this group # The customized event handler of mouseup on the items in this group
on_mouse_up: EventHandler[empty_event] on_mouse_up: EventHandler[no_args_event_spec]
# The customized event handler of mousemove on the items in this group # The customized event handler of mousemove on the items in this group
on_mouse_move: EventHandler[empty_event] on_mouse_move: EventHandler[no_args_event_spec]
# The customized event handler of mouseover on the items in this group # The customized event handler of mouseover on the items in this group
on_mouse_over: EventHandler[empty_event] on_mouse_over: EventHandler[no_args_event_spec]
# The customized event handler of mouseout on the items in this group # The customized event handler of mouseout on the items in this group
on_mouse_out: EventHandler[empty_event] on_mouse_out: EventHandler[no_args_event_spec]
# The customized event handler of mouseenter on the items in this group # The customized event handler of mouseenter on the items in this group
on_mouse_enter: EventHandler[empty_event] on_mouse_enter: EventHandler[no_args_event_spec]
# The customized event handler of mouseleave on the items in this group # The customized event handler of mouseleave on the items in this group
on_mouse_leave: EventHandler[empty_event] on_mouse_leave: EventHandler[no_args_event_spec]
class GraphingTooltip(Recharts): class GraphingTooltip(Recharts):

View File

@ -6,7 +6,7 @@ from typing import Any, Dict, List, Union
from reflex.constants import EventTriggers from reflex.constants import EventTriggers
from reflex.constants.colors import Color from reflex.constants.colors import Color
from reflex.event import EventHandler, empty_event from reflex.event import EventHandler, no_args_event_spec
from reflex.vars.base import LiteralVar, Var from reflex.vars.base import LiteralVar, Var
from .recharts import ( from .recharts import (
@ -103,14 +103,14 @@ class Pie(Recharts):
A dict mapping the event trigger to the var that is passed to the handler. A dict mapping the event trigger to the var that is passed to the handler.
""" """
return { return {
EventTriggers.ON_ANIMATION_START: empty_event, EventTriggers.ON_ANIMATION_START: no_args_event_spec,
EventTriggers.ON_ANIMATION_END: empty_event, EventTriggers.ON_ANIMATION_END: no_args_event_spec,
EventTriggers.ON_CLICK: empty_event, EventTriggers.ON_CLICK: no_args_event_spec,
EventTriggers.ON_MOUSE_MOVE: empty_event, EventTriggers.ON_MOUSE_MOVE: no_args_event_spec,
EventTriggers.ON_MOUSE_OVER: empty_event, EventTriggers.ON_MOUSE_OVER: no_args_event_spec,
EventTriggers.ON_MOUSE_OUT: empty_event, EventTriggers.ON_MOUSE_OUT: no_args_event_spec,
EventTriggers.ON_MOUSE_ENTER: empty_event, EventTriggers.ON_MOUSE_ENTER: no_args_event_spec,
EventTriggers.ON_MOUSE_LEAVE: empty_event, EventTriggers.ON_MOUSE_LEAVE: no_args_event_spec,
} }
@ -167,8 +167,8 @@ class Radar(Recharts):
A dict mapping the event trigger to the var that is passed to the handler. A dict mapping the event trigger to the var that is passed to the handler.
""" """
return { return {
EventTriggers.ON_ANIMATION_START: empty_event, EventTriggers.ON_ANIMATION_START: no_args_event_spec,
EventTriggers.ON_ANIMATION_END: empty_event, EventTriggers.ON_ANIMATION_END: no_args_event_spec,
} }
@ -219,14 +219,14 @@ class RadialBar(Recharts):
A dict mapping the event trigger to the var that is passed to the handler. A dict mapping the event trigger to the var that is passed to the handler.
""" """
return { return {
EventTriggers.ON_CLICK: empty_event, EventTriggers.ON_CLICK: no_args_event_spec,
EventTriggers.ON_MOUSE_MOVE: empty_event, EventTriggers.ON_MOUSE_MOVE: no_args_event_spec,
EventTriggers.ON_MOUSE_OVER: empty_event, EventTriggers.ON_MOUSE_OVER: no_args_event_spec,
EventTriggers.ON_MOUSE_OUT: empty_event, EventTriggers.ON_MOUSE_OUT: no_args_event_spec,
EventTriggers.ON_MOUSE_ENTER: empty_event, EventTriggers.ON_MOUSE_ENTER: no_args_event_spec,
EventTriggers.ON_MOUSE_LEAVE: empty_event, EventTriggers.ON_MOUSE_LEAVE: no_args_event_spec,
EventTriggers.ON_ANIMATION_START: empty_event, EventTriggers.ON_ANIMATION_START: no_args_event_spec,
EventTriggers.ON_ANIMATION_END: empty_event, EventTriggers.ON_ANIMATION_END: no_args_event_spec,
} }
@ -277,28 +277,28 @@ class PolarAngleAxis(Recharts):
_valid_children: List[str] = ["Label"] _valid_children: List[str] = ["Label"]
# The customized event handler of click on the ticks of this axis. # The customized event handler of click on the ticks of this axis.
on_click: EventHandler[empty_event] on_click: EventHandler[no_args_event_spec]
# The customized event handler of mousedown on the the ticks of this axis. # The customized event handler of mousedown on the the ticks of this axis.
on_mouse_down: EventHandler[empty_event] on_mouse_down: EventHandler[no_args_event_spec]
# The customized event handler of mouseup on the ticks of this axis. # The customized event handler of mouseup on the ticks of this axis.
on_mouse_up: EventHandler[empty_event] on_mouse_up: EventHandler[no_args_event_spec]
# The customized event handler of mousemove on the ticks of this axis. # The customized event handler of mousemove on the ticks of this axis.
on_mouse_move: EventHandler[empty_event] on_mouse_move: EventHandler[no_args_event_spec]
# The customized event handler of mouseover on the ticks of this axis. # The customized event handler of mouseover on the ticks of this axis.
on_mouse_over: EventHandler[empty_event] on_mouse_over: EventHandler[no_args_event_spec]
# The customized event handler of mouseout on the ticks of this axis. # The customized event handler of mouseout on the ticks of this axis.
on_mouse_out: EventHandler[empty_event] on_mouse_out: EventHandler[no_args_event_spec]
# The customized event handler of moustenter on the ticks of this axis. # The customized event handler of moustenter on the ticks of this axis.
on_mouse_enter: EventHandler[empty_event] on_mouse_enter: EventHandler[no_args_event_spec]
# The customized event handler of mouseleave on the ticks of this axis. # The customized event handler of mouseleave on the ticks of this axis.
on_mouse_leave: EventHandler[empty_event] on_mouse_leave: EventHandler[no_args_event_spec]
class PolarGrid(Recharts): class PolarGrid(Recharts):
@ -392,12 +392,12 @@ class PolarRadiusAxis(Recharts):
A dict mapping the event trigger to the var that is passed to the handler. A dict mapping the event trigger to the var that is passed to the handler.
""" """
return { return {
EventTriggers.ON_CLICK: empty_event, EventTriggers.ON_CLICK: no_args_event_spec,
EventTriggers.ON_MOUSE_MOVE: empty_event, EventTriggers.ON_MOUSE_MOVE: no_args_event_spec,
EventTriggers.ON_MOUSE_OVER: empty_event, EventTriggers.ON_MOUSE_OVER: no_args_event_spec,
EventTriggers.ON_MOUSE_OUT: empty_event, EventTriggers.ON_MOUSE_OUT: no_args_event_spec,
EventTriggers.ON_MOUSE_ENTER: empty_event, EventTriggers.ON_MOUSE_ENTER: no_args_event_spec,
EventTriggers.ON_MOUSE_LEAVE: empty_event, EventTriggers.ON_MOUSE_LEAVE: no_args_event_spec,
} }

View File

@ -8,10 +8,7 @@ from reflex.base import Base
from reflex.components.component import Component, ComponentNamespace from reflex.components.component import Component, ComponentNamespace
from reflex.components.lucide.icon import Icon from reflex.components.lucide.icon import Icon
from reflex.components.props import NoExtrasAllowedProps, PropsBase from reflex.components.props import NoExtrasAllowedProps, PropsBase
from reflex.event import ( from reflex.event import EventSpec, run_script
EventSpec,
call_script,
)
from reflex.style import Style, resolved_color_mode from reflex.style import Style, resolved_color_mode
from reflex.utils import format from reflex.utils import format
from reflex.utils.imports import ImportVar from reflex.utils.imports import ImportVar
@ -260,7 +257,7 @@ class Toaster(Component):
toast = f"{toast_command}(`{message}`)" toast = f"{toast_command}(`{message}`)"
toast_action = Var(_js_expr=toast) toast_action = Var(_js_expr=toast)
return call_script(toast_action) return run_script(toast_action)
@staticmethod @staticmethod
def toast_info(message: str = "", **kwargs): def toast_info(message: str = "", **kwargs):
@ -336,7 +333,7 @@ class Toaster(Component):
dismiss_action = Var( dismiss_action = Var(
_js_expr=dismiss, _var_data=VarData.merge(dismiss_var_data) _js_expr=dismiss, _var_data=VarData.merge(dismiss_var_data)
) )
return call_script(dismiss_action) return run_script(dismiss_action)
@classmethod @classmethod
def create(cls, *children, **props) -> Component: def create(cls, *children, **props) -> Component:

View File

@ -7,7 +7,7 @@ from typing import Dict, List, Literal, Optional, Tuple, Union
from reflex.base import Base from reflex.base import Base
from reflex.components.component import Component, NoSSRComponent from reflex.components.component import Component, NoSSRComponent
from reflex.event import EventHandler, empty_event, identity_event from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
from reflex.utils.format import to_camel_case from reflex.utils.format import to_camel_case
from reflex.utils.imports import ImportDict, ImportVar from reflex.utils.imports import ImportDict, ImportVar
from reflex.vars.base import Var from reflex.vars.base import Var
@ -207,31 +207,31 @@ class Editor(NoSSRComponent):
disable_toolbar: Var[bool] disable_toolbar: Var[bool]
# Fired when the editor content changes. # Fired when the editor content changes.
on_change: EventHandler[identity_event(str)] on_change: EventHandler[passthrough_event_spec(str)]
# Fired when the something is inputted in the editor. # Fired when the something is inputted in the editor.
on_input: EventHandler[empty_event] on_input: EventHandler[no_args_event_spec]
# Fired when the editor loses focus. # Fired when the editor loses focus.
on_blur: EventHandler[on_blur_spec] on_blur: EventHandler[on_blur_spec]
# Fired when the editor is loaded. # Fired when the editor is loaded.
on_load: EventHandler[identity_event(bool)] on_load: EventHandler[passthrough_event_spec(bool)]
# Fired when the editor content is copied. # Fired when the editor content is copied.
on_copy: EventHandler[empty_event] on_copy: EventHandler[no_args_event_spec]
# Fired when the editor content is cut. # Fired when the editor content is cut.
on_cut: EventHandler[empty_event] on_cut: EventHandler[no_args_event_spec]
# Fired when the editor content is pasted. # Fired when the editor content is pasted.
on_paste: EventHandler[on_paste_spec] on_paste: EventHandler[on_paste_spec]
# Fired when the code view is toggled. # Fired when the code view is toggled.
toggle_code_view: EventHandler[identity_event(bool)] toggle_code_view: EventHandler[passthrough_event_spec(bool)]
# Fired when the full screen mode is toggled. # Fired when the full screen mode is toggled.
toggle_full_screen: EventHandler[identity_event(bool)] toggle_full_screen: EventHandler[passthrough_event_spec(bool)]
def add_imports(self) -> ImportDict: def add_imports(self) -> ImportDict:
"""Add imports for the Editor component. """Add imports for the Editor component.

View File

@ -466,7 +466,7 @@ def key_event(e: Var[JavasciptKeyboardEvent]) -> Tuple[Var[str]]:
return (e.key,) return (e.key,)
def empty_event() -> Tuple[()]: def no_args_event_spec() -> Tuple[()]:
"""Empty event handler. """Empty event handler.
Returns: Returns:
@ -476,43 +476,14 @@ def empty_event() -> Tuple[()]:
# These chains can be used for their side effects when no other events are desired. # These chains can be used for their side effects when no other events are desired.
stop_propagation = EventChain(events=[], args_spec=empty_event).stop_propagation stop_propagation = EventChain(events=[], args_spec=no_args_event_spec).stop_propagation
prevent_default = EventChain(events=[], args_spec=empty_event).prevent_default prevent_default = EventChain(events=[], args_spec=no_args_event_spec).prevent_default
T = TypeVar("T") T = TypeVar("T")
U = TypeVar("U") U = TypeVar("U")
# def identity_event(event_type: Type[T]) -> Callable[[Var[T]], Tuple[Var[T]]]:
# """A helper function that returns the input event as output.
# Args:
# event_type: The type of the event.
# Returns:
# A function that returns the input event as output.
# """
# def inner(ev: Var[T]) -> Tuple[Var[T]]:
# return (ev,)
# inner.__signature__ = inspect.signature(inner).replace( # type: ignore
# parameters=[
# inspect.Parameter(
# "ev",
# kind=inspect.Parameter.POSITIONAL_OR_KEYWORD,
# annotation=Var[event_type],
# )
# ],
# return_annotation=Tuple[Var[event_type]],
# )
# inner.__annotations__["ev"] = Var[event_type]
# inner.__annotations__["return"] = Tuple[Var[event_type]]
# return inner
class IdentityEventReturn(Generic[T], Protocol): class IdentityEventReturn(Generic[T], Protocol):
"""Protocol for an identity event return.""" """Protocol for an identity event return."""
@ -529,20 +500,22 @@ class IdentityEventReturn(Generic[T], Protocol):
@overload @overload
def identity_event(event_type: Type[T], /) -> Callable[[Var[T]], Tuple[Var[T]]]: ... # type: ignore def passthrough_event_spec(
event_type: Type[T], /
) -> Callable[[Var[T]], Tuple[Var[T]]]: ... # type: ignore
@overload @overload
def identity_event( def passthrough_event_spec(
event_type_1: Type[T], event_type2: Type[U], / event_type_1: Type[T], event_type2: Type[U], /
) -> Callable[[Var[T], Var[U]], Tuple[Var[T], Var[U]]]: ... ) -> Callable[[Var[T], Var[U]], Tuple[Var[T], Var[U]]]: ...
@overload @overload
def identity_event(*event_types: Type[T]) -> IdentityEventReturn[T]: ... def passthrough_event_spec(*event_types: Type[T]) -> IdentityEventReturn[T]: ...
def identity_event(*event_types: Type[T]) -> IdentityEventReturn[T]: # type: ignore def passthrough_event_spec(*event_types: Type[T]) -> IdentityEventReturn[T]: # type: ignore
"""A helper function that returns the input event as output. """A helper function that returns the input event as output.
Args: Args:
@ -733,7 +706,16 @@ def console_log(message: str | Var[str]) -> EventSpec:
Returns: Returns:
An event to log the message. An event to log the message.
""" """
return server_side("_console", get_fn_signature(console_log), message=message) return run_script(Var("console").to(dict).log.to(FunctionVar).call(message))
def noop() -> EventSpec:
"""Do nothing.
Returns:
An event to do nothing.
"""
return run_script(Var.create(None))
def back() -> EventSpec: def back() -> EventSpec:
@ -742,7 +724,9 @@ def back() -> EventSpec:
Returns: Returns:
An event to go back one page. An event to go back one page.
""" """
return call_script("window.history.back()") return run_script(
Var("window").to(dict).history.to(dict).back.to(FunctionVar).call()
)
def window_alert(message: str | Var[str]) -> EventSpec: def window_alert(message: str | Var[str]) -> EventSpec:
@ -754,7 +738,7 @@ def window_alert(message: str | Var[str]) -> EventSpec:
Returns: Returns:
An event to alert the message. An event to alert the message.
""" """
return server_side("_alert", get_fn_signature(window_alert), message=message) return run_script(Var("window").to(dict).alert.to(FunctionVar).call(message))
def set_focus(ref: str) -> EventSpec: def set_focus(ref: str) -> EventSpec:
@ -785,12 +769,12 @@ def scroll_to(elem_id: str, align_to_top: bool | Var[bool] = True) -> EventSpec:
""" """
get_element_by_id = FunctionStringVar.create("document.getElementById") get_element_by_id = FunctionStringVar.create("document.getElementById")
return call_script( return run_script(
get_element_by_id(elem_id) get_element_by_id(elem_id)
.call(elem_id) .call(elem_id)
.to(ObjectVar) .to(ObjectVar)
.scrollIntoView.to(FunctionVar) .scrollIntoView.to(FunctionVar)
.call(align_to_top) .call(align_to_top),
) )
@ -897,10 +881,12 @@ def set_clipboard(content: str) -> EventSpec:
Returns: Returns:
EventSpec: An event to set some content in the clipboard. EventSpec: An event to set some content in the clipboard.
""" """
return server_side( return run_script(
"_set_clipboard", Var("navigator")
get_fn_signature(set_clipboard), .to(dict)
content=content, .clipboard.to(dict)
.writeText.to(FunctionVar)
.call(content)
) )
@ -987,13 +973,7 @@ def _callback_arg_spec(eval_result):
def call_script( def call_script(
javascript_code: str | Var[str], javascript_code: str | Var[str],
callback: ( callback: EventType | None = None,
EventSpec
| EventHandler
| Callable
| List[EventSpec | EventHandler | Callable]
| None
) = None,
) -> EventSpec: ) -> EventSpec:
"""Create an event handler that executes arbitrary javascript code. """Create an event handler that executes arbitrary javascript code.
@ -1007,12 +987,10 @@ def call_script(
callback_kwargs = {} callback_kwargs = {}
if callback is not None: if callback is not None:
callback_kwargs = { callback_kwargs = {
"callback": str( "callback": format.format_queue_events(
format.format_queue_events(
callback, callback,
args_spec=lambda result: [result], args_spec=lambda result: [result],
), )._js_expr,
),
} }
if isinstance(javascript_code, str): if isinstance(javascript_code, str):
# When there is VarData, include it and eval the JS code inline on the client. # When there is VarData, include it and eval the JS code inline on the client.
@ -1032,6 +1010,62 @@ def call_script(
) )
def call_function(
javascript_code: str | Var,
callback: EventType | None = None,
) -> EventSpec:
"""Create an event handler that executes arbitrary javascript code.
Args:
javascript_code: The code to execute.
callback: EventHandler that will receive the result of evaluating the javascript code.
Returns:
EventSpec: An event that will execute the client side javascript.
"""
callback_kwargs = {}
if callback is not None:
callback_kwargs = {
"callback": format.format_queue_events(
callback,
args_spec=lambda result: [result],
),
}
javascript_code = (
Var(javascript_code) if isinstance(javascript_code, str) else javascript_code
)
return server_side(
"_call_function",
get_fn_signature(call_function),
function=javascript_code,
**callback_kwargs,
)
def run_script(
javascript_code: str | Var,
callback: EventType | None = None,
) -> EventSpec:
"""Create an event handler that executes arbitrary javascript code.
Args:
javascript_code: The code to execute.
callback: EventHandler that will receive the result of evaluating the javascript code.
Returns:
EventSpec: An event that will execute the client side javascript.
"""
javascript_code = (
Var(javascript_code) if isinstance(javascript_code, str) else javascript_code
)
return call_function(
ArgsFunctionOperation.create(tuple(), javascript_code), callback
)
def get_event(state, event): def get_event(state, event):
"""Get the event from the given state. """Get the event from the given state.
@ -1822,13 +1856,14 @@ class EventNamespace(types.SimpleNamespace):
check_fn_match_arg_spec = staticmethod(check_fn_match_arg_spec) check_fn_match_arg_spec = staticmethod(check_fn_match_arg_spec)
resolve_annotation = staticmethod(resolve_annotation) resolve_annotation = staticmethod(resolve_annotation)
parse_args_spec = staticmethod(parse_args_spec) parse_args_spec = staticmethod(parse_args_spec)
identity_event = staticmethod(identity_event) passthrough_event_spec = staticmethod(passthrough_event_spec)
input_event = staticmethod(input_event) input_event = staticmethod(input_event)
key_event = staticmethod(key_event) key_event = staticmethod(key_event)
empty_event = staticmethod(empty_event) no_args_event_spec = staticmethod(no_args_event_spec)
server_side = staticmethod(server_side) server_side = staticmethod(server_side)
redirect = staticmethod(redirect) redirect = staticmethod(redirect)
console_log = staticmethod(console_log) console_log = staticmethod(console_log)
noop = staticmethod(noop)
back = staticmethod(back) back = staticmethod(back)
window_alert = staticmethod(window_alert) window_alert = staticmethod(window_alert)
set_focus = staticmethod(set_focus) set_focus = staticmethod(set_focus)
@ -1842,6 +1877,8 @@ class EventNamespace(types.SimpleNamespace):
set_clipboard = staticmethod(set_clipboard) set_clipboard = staticmethod(set_clipboard)
download = staticmethod(download) download = staticmethod(download)
call_script = staticmethod(call_script) call_script = staticmethod(call_script)
call_function = staticmethod(call_function)
run_script = staticmethod(run_script)
event = EventNamespace() event = EventNamespace()

View File

@ -8,7 +8,7 @@ import sys
from typing import Any, Callable, Union from typing import Any, Callable, Union
from reflex import constants from reflex import constants
from reflex.event import EventChain, EventHandler, EventSpec, call_script from reflex.event import EventChain, EventHandler, EventSpec, run_script
from reflex.utils.imports import ImportVar from reflex.utils.imports import ImportVar
from reflex.vars import ( from reflex.vars import (
VarData, VarData,
@ -227,7 +227,7 @@ class ClientStateVar(Var):
""" """
if not self._global_ref: if not self._global_ref:
raise ValueError("ClientStateVar must be global to retrieve the value.") raise ValueError("ClientStateVar must be global to retrieve the value.")
return call_script(_client_state_ref(self._getter_name), callback=callback) return run_script(_client_state_ref(self._getter_name), callback=callback)
def push(self, value: Any) -> EventSpec: def push(self, value: Any) -> EventSpec:
"""Push a value to the client state variable from the backend. """Push a value to the client state variable from the backend.
@ -245,4 +245,4 @@ class ClientStateVar(Var):
""" """
if not self._global_ref: if not self._global_ref:
raise ValueError("ClientStateVar must be global to push the value.") raise ValueError("ClientStateVar must be global to push the value.")
return call_script(f"{_client_state_ref(self._setter_name)}({value})") return run_script(f"{_client_state_ref(self._setter_name)}({value})")

View File

@ -12,7 +12,7 @@ from reflex.components.radix.themes.components.icon_button import IconButton
from reflex.components.radix.themes.layout.box import Box from reflex.components.radix.themes.layout.box import Box
from reflex.components.radix.themes.layout.container import Container from reflex.components.radix.themes.layout.container import Container
from reflex.components.radix.themes.layout.stack import HStack from reflex.components.radix.themes.layout.stack import HStack
from reflex.event import call_script from reflex.event import run_script
from reflex.experimental import hooks from reflex.experimental import hooks
from reflex.state import ComponentState from reflex.state import ComponentState
from reflex.style import Style from reflex.style import Style
@ -173,7 +173,7 @@ class SidebarTrigger(Fragment):
else: else:
open, toggle = ( open, toggle = (
Var(_js_expr="open"), Var(_js_expr="open"),
call_script(Var(_js_expr="setOpen(!open)")), run_script("setOpen(!open)"),
) )
trigger_props["left"] = cond(open, f"calc({sidebar_width} - 32px)", "0") trigger_props["left"] = cond(open, f"calc({sidebar_width} - 32px)", "0")

View File

@ -8,6 +8,7 @@ import copy
import dataclasses import dataclasses
import functools import functools
import inspect import inspect
import json
import pickle import pickle
import sys import sys
import uuid import uuid
@ -104,6 +105,8 @@ var = computed_var
# If the state is this large, it's considered a performance issue. # If the state is this large, it's considered a performance issue.
TOO_LARGE_SERIALIZED_STATE = 100 * 1024 # 100kb TOO_LARGE_SERIALIZED_STATE = 100 * 1024 # 100kb
# Only warn about each state class size once.
_WARNED_ABOUT_STATE_SIZE: Set[str] = set()
# Errors caught during pickling of state # Errors caught during pickling of state
HANDLED_PICKLE_ERRORS = ( HANDLED_PICKLE_ERRORS = (
@ -353,7 +356,6 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
def __init__( def __init__(
self, self,
*args,
parent_state: BaseState | None = None, parent_state: BaseState | None = None,
init_substates: bool = True, init_substates: bool = True,
_reflex_internal_init: bool = False, _reflex_internal_init: bool = False,
@ -364,11 +366,10 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
DO NOT INSTANTIATE STATE CLASSES DIRECTLY! Use StateManager.get_state() instead. DO NOT INSTANTIATE STATE CLASSES DIRECTLY! Use StateManager.get_state() instead.
Args: Args:
*args: The args to pass to the Pydantic init method.
parent_state: The parent state. parent_state: The parent state.
init_substates: Whether to initialize the substates in this instance. init_substates: Whether to initialize the substates in this instance.
_reflex_internal_init: A flag to indicate that the state is being initialized by the framework. _reflex_internal_init: A flag to indicate that the state is being initialized by the framework.
**kwargs: The kwargs to pass to the Pydantic init method. **kwargs: The kwargs to set as attributes on the state.
Raises: Raises:
ReflexRuntimeError: If the state is instantiated directly by end user. ReflexRuntimeError: If the state is instantiated directly by end user.
@ -381,7 +382,9 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
"See https://reflex.dev/docs/state/ for further information." "See https://reflex.dev/docs/state/ for further information."
) )
kwargs["parent_state"] = parent_state kwargs["parent_state"] = parent_state
super().__init__(*args, **kwargs) super().__init__()
for name, value in kwargs.items():
setattr(self, name, value)
# Setup the substates (for memory state manager only). # Setup the substates (for memory state manager only).
if init_substates: if init_substates:
@ -1285,9 +1288,12 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
fields = self.get_fields() fields = self.get_fields()
if name in fields and not _isinstance( if name in fields:
value, (field_type := fields[name].outer_type_) field = fields[name]
): field_type = field.outer_type_
if field.allow_none:
field_type = Union[field_type, None]
if not _isinstance(value, field_type):
console.deprecate( console.deprecate(
"mismatched-type-assignment", "mismatched-type-assignment",
f"Tried to assign value {value} of type {type(value)} to field {type(self).__name__}.{name} of type {field_type}." f"Tried to assign value {value} of type {type(value)} to field {type(self).__name__}.{name} of type {field_type}."
@ -2046,6 +2052,27 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
state["__dict__"].pop(inherited_var_name, None) state["__dict__"].pop(inherited_var_name, None)
return state return state
def _warn_if_too_large(
self,
pickle_state_size: int,
):
"""Print a warning when the state is too large.
Args:
pickle_state_size: The size of the pickled state.
"""
state_full_name = self.get_full_name()
if (
state_full_name not in _WARNED_ABOUT_STATE_SIZE
and pickle_state_size > TOO_LARGE_SERIALIZED_STATE
and self.substates
):
console.warn(
f"State {state_full_name} serializes to {pickle_state_size} bytes "
"which may present performance issues. Consider reducing the size of this state."
)
_WARNED_ABOUT_STATE_SIZE.add(state_full_name)
@classmethod @classmethod
@functools.lru_cache() @functools.lru_cache()
def _to_schema(cls) -> str: def _to_schema(cls) -> str:
@ -2084,7 +2111,9 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
The serialized state. The serialized state.
""" """
try: try:
return pickle.dumps((self._to_schema(), self)) pickle_state = pickle.dumps((self._to_schema(), self))
self._warn_if_too_large(len(pickle_state))
return pickle_state
except HANDLED_PICKLE_ERRORS as og_pickle_error: except HANDLED_PICKLE_ERRORS as og_pickle_error:
error = ( error = (
f"Failed to serialize state {self.get_full_name()} due to unpicklable object. " f"Failed to serialize state {self.get_full_name()} due to unpicklable object. "
@ -3075,9 +3104,6 @@ class StateManagerRedis(StateManager):
b"evicted", b"evicted",
} }
# Only warn about each state class size once.
_warned_about_state_size: ClassVar[Set[str]] = set()
async def _get_parent_state( async def _get_parent_state(
self, token: str, state: BaseState | None = None self, token: str, state: BaseState | None = None
) -> BaseState | None: ) -> BaseState | None:
@ -3221,29 +3247,6 @@ class StateManagerRedis(StateManager):
return state._get_root_state() return state._get_root_state()
return state return state
def _warn_if_too_large(
self,
state: BaseState,
pickle_state_size: int,
):
"""Print a warning when the state is too large.
Args:
state: The state to check.
pickle_state_size: The size of the pickled state.
"""
state_full_name = state.get_full_name()
if (
state_full_name not in self._warned_about_state_size
and pickle_state_size > TOO_LARGE_SERIALIZED_STATE
and state.substates
):
console.warn(
f"State {state_full_name} serializes to {pickle_state_size} bytes "
"which may present performance issues. Consider reducing the size of this state."
)
self._warned_about_state_size.add(state_full_name)
@override @override
async def set_state( async def set_state(
self, self,
@ -3294,7 +3297,6 @@ class StateManagerRedis(StateManager):
# Persist only the given state (parents or substates are excluded by BaseState.__getstate__). # Persist only the given state (parents or substates are excluded by BaseState.__getstate__).
if state._get_was_touched(): if state._get_was_touched():
pickle_state = state._serialize() pickle_state = state._serialize()
self._warn_if_too_large(state, len(pickle_state))
if pickle_state: if pickle_state:
await self.redis.set( await self.redis.set(
_substate_key(client_token, state), _substate_key(client_token, state),
@ -3715,6 +3717,29 @@ def serialize_mutable_proxy(mp: MutableProxy):
return mp.__wrapped__ return mp.__wrapped__
_orig_json_JSONEncoder_default = json.JSONEncoder.default
def _json_JSONEncoder_default_wrapper(self: json.JSONEncoder, o: Any) -> Any:
"""Wrap JSONEncoder.default to handle MutableProxy objects.
Args:
self: the JSONEncoder instance.
o: the object to serialize.
Returns:
A JSON-able object.
"""
try:
return o.__wrapped__
except AttributeError:
pass
return _orig_json_JSONEncoder_default(self, o)
json.JSONEncoder.default = _json_JSONEncoder_default_wrapper
class ImmutableMutableProxy(MutableProxy): class ImmutableMutableProxy(MutableProxy):
"""A proxy for a mutable object that tracks changes. """A proxy for a mutable object that tracks changes.

View File

@ -467,9 +467,11 @@ def output_system_info():
console.debug(f"{dep}") console.debug(f"{dep}")
console.debug( console.debug(
f"Using package installer at: {prerequisites.get_install_package_manager()}" # type: ignore f"Using package installer at: {prerequisites.get_install_package_manager(on_failure_return_none=True)}" # type: ignore
) )
console.debug(f"Using package executer at: {prerequisites.get_package_manager()}") # type: ignore console.debug(
f"Using package executer at: {prerequisites.get_package_manager(on_failure_return_none=True)}"
) # type: ignore
if system != "Windows": if system != "Windows":
console.debug(f"Unzip path: {path_ops.which('unzip')}") console.debug(f"Unzip path: {path_ops.which('unzip')}")

View File

@ -6,7 +6,7 @@ import inspect
import json import json
import os import os
import re import re
from typing import TYPE_CHECKING, Any, Callable, List, Optional, Union from typing import TYPE_CHECKING, Any, List, Optional, Union
from reflex import constants from reflex import constants
from reflex.utils import exceptions from reflex.utils import exceptions
@ -14,7 +14,7 @@ from reflex.utils.console import deprecate
if TYPE_CHECKING: if TYPE_CHECKING:
from reflex.components.component import ComponentStyle from reflex.components.component import ComponentStyle
from reflex.event import ArgsSpec, EventChain, EventHandler, EventSpec from reflex.event import ArgsSpec, EventChain, EventHandler, EventSpec, EventType
WRAP_MAP = { WRAP_MAP = {
"{": "}", "{": "}",
@ -533,13 +533,7 @@ def format_event_chain(
def format_queue_events( def format_queue_events(
events: ( events: EventType | None = None,
EventSpec
| EventHandler
| Callable
| List[EventSpec | EventHandler | Callable]
| None
) = None,
args_spec: Optional[ArgsSpec] = None, args_spec: Optional[ArgsSpec] = None,
) -> Var[EventChain]: ) -> Var[EventChain]:
"""Format a list of event handler / event spec as a javascript callback. """Format a list of event handler / event spec as a javascript callback.

View File

@ -204,10 +204,13 @@ def get_bun_version() -> version.Version | None:
return None return None
def get_install_package_manager() -> str | None: def get_install_package_manager(on_failure_return_none: bool = False) -> str | None:
"""Get the package manager executable for installation. """Get the package manager executable for installation.
Currently, bun is used for installation only. Currently, bun is used for installation only.
Args:
on_failure_return_none: Whether to return None on failure.
Returns: Returns:
The path to the package manager. The path to the package manager.
""" """
@ -217,21 +220,29 @@ def get_install_package_manager() -> str | None:
or windows_check_onedrive_in_path() or windows_check_onedrive_in_path()
or windows_npm_escape_hatch() or windows_npm_escape_hatch()
): ):
return get_package_manager() return get_package_manager(on_failure_return_none)
return str(get_config().bun_path) return str(get_config().bun_path)
def get_package_manager() -> str | None: def get_package_manager(on_failure_return_none: bool = False) -> str | None:
"""Get the package manager executable for running app. """Get the package manager executable for running app.
Currently on unix systems, npm is used for running the app only. Currently on unix systems, npm is used for running the app only.
Args:
on_failure_return_none: Whether to return None on failure.
Returns: Returns:
The path to the package manager. The path to the package manager.
Raises:
FileNotFoundError: If the package manager is not found.
""" """
npm_path = path_ops.get_npm_path() npm_path = path_ops.get_npm_path()
if npm_path is not None: if npm_path is not None:
npm_path = str(Path(npm_path).resolve()) return str(Path(npm_path).resolve())
return npm_path if on_failure_return_none:
return None
raise FileNotFoundError("NPM not found. You may need to run `reflex init`.")
def windows_check_onedrive_in_path() -> bool: def windows_check_onedrive_in_path() -> bool:
@ -430,7 +441,7 @@ def create_config(app_name: str):
def initialize_gitignore( def initialize_gitignore(
gitignore_file: Path = constants.GitIgnore.FILE, gitignore_file: Path = constants.GitIgnore.FILE,
files_to_ignore: set[str] = constants.GitIgnore.DEFAULTS, files_to_ignore: set[str] | list[str] = constants.GitIgnore.DEFAULTS,
): ):
"""Initialize the template .gitignore file. """Initialize the template .gitignore file.
@ -439,23 +450,20 @@ def initialize_gitignore(
files_to_ignore: The files to add to the .gitignore file. files_to_ignore: The files to add to the .gitignore file.
""" """
# Combine with the current ignored files. # Combine with the current ignored files.
current_ignore: set[str] = set() current_ignore: list[str] = []
if gitignore_file.exists(): if gitignore_file.exists():
current_ignore |= set( current_ignore = [ln.strip() for ln in gitignore_file.read_text().splitlines()]
line.strip() for line in gitignore_file.read_text().splitlines()
)
if files_to_ignore == current_ignore: if files_to_ignore == current_ignore:
console.debug(f"{gitignore_file} already up to date.") console.debug(f"{gitignore_file} already up to date.")
return return
files_to_ignore |= current_ignore files_to_ignore = [ln for ln in files_to_ignore if ln not in current_ignore]
files_to_ignore += current_ignore
# Write files to the .gitignore file. # Write files to the .gitignore file.
gitignore_file.touch(exist_ok=True) gitignore_file.touch(exist_ok=True)
console.debug(f"Creating {gitignore_file}") console.debug(f"Creating {gitignore_file}")
gitignore_file.write_text( gitignore_file.write_text("\n".join(files_to_ignore) + "\n")
"\n".join(sorted(files_to_ignore)) + "\n",
)
def initialize_requirements_txt(): def initialize_requirements_txt():
@ -920,20 +928,39 @@ def install_frontend_packages(packages: set[str], config: Config):
packages: A list of package names to be installed. packages: A list of package names to be installed.
config: The config object. config: The config object.
Raises:
FileNotFoundError: If the package manager is not found.
Example: Example:
>>> install_frontend_packages(["react", "react-dom"], get_config()) >>> install_frontend_packages(["react", "react-dom"], get_config())
""" """
# unsupported archs(arm and 32bit machines) will use npm anyway. so we dont have to run npm twice # unsupported archs(arm and 32bit machines) will use npm anyway. so we dont have to run npm twice
fallback_command = ( fallback_command = (
get_package_manager() get_package_manager(on_failure_return_none=True)
if not constants.IS_WINDOWS if (
not constants.IS_WINDOWS
or constants.IS_WINDOWS or constants.IS_WINDOWS
and is_windows_bun_supported() and is_windows_bun_supported()
and not windows_check_onedrive_in_path() and not windows_check_onedrive_in_path()
)
else None else None
) )
install_package_manager = (
get_install_package_manager(on_failure_return_none=True) or fallback_command
)
if install_package_manager is None:
raise FileNotFoundError(
"Could not find a package manager to install frontend packages. You may need to run `reflex init`."
)
fallback_command = (
fallback_command if fallback_command is not install_package_manager else None
)
processes.run_process_with_fallback( processes.run_process_with_fallback(
[get_install_package_manager(), "install"], # type: ignore [install_package_manager, "install"], # type: ignore
fallback=fallback_command, fallback=fallback_command,
analytics_enabled=True, analytics_enabled=True,
show_status_message="Installing base frontend packages", show_status_message="Installing base frontend packages",
@ -944,7 +971,7 @@ def install_frontend_packages(packages: set[str], config: Config):
if config.tailwind is not None: if config.tailwind is not None:
processes.run_process_with_fallback( processes.run_process_with_fallback(
[ [
get_install_package_manager(), install_package_manager,
"add", "add",
"-d", "-d",
constants.Tailwind.VERSION, constants.Tailwind.VERSION,
@ -960,7 +987,7 @@ def install_frontend_packages(packages: set[str], config: Config):
# Install custom packages defined in frontend_packages # Install custom packages defined in frontend_packages
if len(packages) > 0: if len(packages) > 0:
processes.run_process_with_fallback( processes.run_process_with_fallback(
[get_install_package_manager(), "add", *packages], [install_package_manager, "add", *packages],
fallback=fallback_command, fallback=fallback_command,
analytics_enabled=True, analytics_enabled=True,
show_status_message="Installing frontend packages from config and components", show_status_message="Installing frontend packages from config and components",

View File

@ -570,6 +570,12 @@ def _isinstance(obj: Any, cls: GenericType, nested: bool = False) -> bool:
_isinstance(item, args[0]) for item in obj _isinstance(item, args[0]) for item in obj
) )
if args:
from reflex.vars import Field
if origin is Field:
return _isinstance(obj, args[0])
return isinstance(obj, get_base_class(cls)) return isinstance(obj, get_base_class(cls))

View File

@ -4,6 +4,7 @@ from __future__ import annotations
import asyncio import asyncio
import time import time
from pathlib import Path
from typing import Generator from typing import Generator
import pytest import pytest
@ -205,11 +206,12 @@ async def test_upload_file(
file_data = await AppHarness._poll_for_async(get_file_data) file_data = await AppHarness._poll_for_async(get_file_data)
assert isinstance(file_data, dict) assert isinstance(file_data, dict)
assert file_data[exp_name] == exp_contents normalized_file_data = {Path(k).name: v for k, v in file_data.items()}
assert normalized_file_data[Path(exp_name).name] == exp_contents
# check that the selected files are displayed # check that the selected files are displayed
selected_files = driver.find_element(By.ID, f"selected_files{suffix}") selected_files = driver.find_element(By.ID, f"selected_files{suffix}")
assert selected_files.text == exp_name assert Path(selected_files.text).name == Path(exp_name).name
state = await upload_file.get_state(substate_token) state = await upload_file.get_state(substate_token)
if secondary: if secondary:
@ -256,7 +258,9 @@ async def test_upload_file_multiple(tmp_path, upload_file: AppHarness, driver):
# check that the selected files are displayed # check that the selected files are displayed
selected_files = driver.find_element(By.ID, "selected_files") selected_files = driver.find_element(By.ID, "selected_files")
assert selected_files.text == "\n".join(exp_files) assert [Path(name).name for name in selected_files.text.split("\n")] == [
Path(name).name for name in exp_files
]
# do the upload # do the upload
upload_button.click() upload_button.click()
@ -271,8 +275,9 @@ async def test_upload_file_multiple(tmp_path, upload_file: AppHarness, driver):
file_data = await AppHarness._poll_for_async(get_file_data) file_data = await AppHarness._poll_for_async(get_file_data)
assert isinstance(file_data, dict) assert isinstance(file_data, dict)
normalized_file_data = {Path(k).name: v for k, v in file_data.items()}
for exp_name, exp_contents in exp_files.items(): for exp_name, exp_contents in exp_files.items():
assert file_data[exp_name] == exp_contents assert normalized_file_data[Path(exp_name).name] == exp_contents
@pytest.mark.parametrize("secondary", [False, True]) @pytest.mark.parametrize("secondary", [False, True])
@ -317,7 +322,9 @@ def test_clear_files(
# check that the selected files are displayed # check that the selected files are displayed
selected_files = driver.find_element(By.ID, f"selected_files{suffix}") selected_files = driver.find_element(By.ID, f"selected_files{suffix}")
assert selected_files.text == "\n".join(exp_files) assert [Path(name).name for name in selected_files.text.split("\n")] == [
Path(name).name for name in exp_files
]
clear_button = driver.find_element(By.ID, f"clear_button{suffix}") clear_button = driver.find_element(By.ID, f"clear_button{suffix}")
assert clear_button assert clear_button
@ -369,6 +376,9 @@ async def test_cancel_upload(tmp_path, upload_file: AppHarness, driver: WebDrive
# look up the backend state and assert on progress # look up the backend state and assert on progress
state = await upload_file.get_state(substate_token) state = await upload_file.get_state(substate_token)
assert state.substates[state_name].progress_dicts assert state.substates[state_name].progress_dicts
assert exp_name not in state.substates[state_name]._file_data file_data = state.substates[state_name]._file_data
assert isinstance(file_data, dict)
normalized_file_data = {Path(k).name: v for k, v in file_data.items()}
assert Path(exp_name).name not in normalized_file_data
target_file.unlink() target_file.unlink()

View File

@ -19,10 +19,10 @@ from reflex.constants import EventTriggers
from reflex.event import ( from reflex.event import (
EventChain, EventChain,
EventHandler, EventHandler,
empty_event,
identity_event,
input_event, input_event,
no_args_event_spec,
parse_args_spec, parse_args_spec,
passthrough_event_spec,
) )
from reflex.state import BaseState from reflex.state import BaseState
from reflex.style import Style from reflex.style import Style
@ -111,10 +111,10 @@ def component2() -> Type[Component]:
""" """
return { return {
**super().get_event_triggers(), **super().get_event_triggers(),
"on_open": identity_event(bool), "on_open": passthrough_event_spec(bool),
"on_close": identity_event(bool), "on_close": passthrough_event_spec(bool),
"on_user_visited_count_changed": identity_event(int), "on_user_visited_count_changed": passthrough_event_spec(int),
"on_user_list_changed": identity_event(List[str]), "on_user_list_changed": passthrough_event_spec(List[str]),
} }
def _get_imports(self) -> ParsedImportDict: def _get_imports(self) -> ParsedImportDict:
@ -1821,8 +1821,8 @@ def test_custom_component_declare_event_handlers_in_fields():
class TestComponent(Component): class TestComponent(Component):
on_a: EventHandler[lambda e0: [e0]] on_a: EventHandler[lambda e0: [e0]]
on_b: EventHandler[input_event] on_b: EventHandler[input_event]
on_c: EventHandler[empty_event] on_c: EventHandler[no_args_event_spec]
on_d: EventHandler[empty_event] on_d: EventHandler[no_args_event_spec]
on_e: EventHandler on_e: EventHandler
on_f: EventHandler[lambda a, b, c: [c, b, a]] on_f: EventHandler[lambda a, b, c: [c, b, a]]

View File

@ -3,7 +3,7 @@ from __future__ import annotations
from typing import Any from typing import Any
from reflex.components.component import Component from reflex.components.component import Component
from reflex.event import EventHandler, empty_event, input_event from reflex.event import EventHandler, input_event, no_args_event_spec
# This is a repeat of its namesake in test_component.py. # This is a repeat of its namesake in test_component.py.
@ -26,8 +26,8 @@ def test_custom_component_declare_event_handlers_in_fields():
class TestComponent(Component): class TestComponent(Component):
on_a: EventHandler[lambda e0: [e0]] on_a: EventHandler[lambda e0: [e0]]
on_b: EventHandler[input_event] on_b: EventHandler[input_event]
on_c: EventHandler[empty_event] on_c: EventHandler[no_args_event_spec]
on_d: EventHandler[empty_event] on_d: EventHandler[no_args_event_spec]
custom_component = ReferenceComponent.create() custom_component = ReferenceComponent.create()
test_component = TestComponent.create() test_component = TestComponent.create()

View File

@ -1,4 +1,4 @@
from typing import List from typing import Callable, List
import pytest import pytest
@ -216,24 +216,40 @@ def test_event_console_log():
"""Test the event console log function.""" """Test the event console log function."""
spec = event.console_log("message") spec = event.console_log("message")
assert isinstance(spec, EventSpec) assert isinstance(spec, EventSpec)
assert spec.handler.fn.__qualname__ == "_console" assert spec.handler.fn.__qualname__ == "_call_function"
assert spec.args[0][0].equals(Var(_js_expr="message")) assert spec.args[0][0].equals(Var(_js_expr="function"))
assert spec.args[0][1].equals(LiteralVar.create("message")) assert spec.args[0][1].equals(
assert format.format_event(spec) == 'Event("_console", {message:"message"})' Var('(() => ((console["log"]("message"))))', _var_type=Callable)
)
assert (
format.format_event(spec)
== 'Event("_call_function", {function:(() => ((console["log"]("message"))))})'
)
spec = event.console_log(Var(_js_expr="message")) spec = event.console_log(Var(_js_expr="message"))
assert format.format_event(spec) == 'Event("_console", {message:message})' assert (
format.format_event(spec)
== 'Event("_call_function", {function:(() => ((console["log"](message))))})'
)
def test_event_window_alert(): def test_event_window_alert():
"""Test the event window alert function.""" """Test the event window alert function."""
spec = event.window_alert("message") spec = event.window_alert("message")
assert isinstance(spec, EventSpec) assert isinstance(spec, EventSpec)
assert spec.handler.fn.__qualname__ == "_alert" assert spec.handler.fn.__qualname__ == "_call_function"
assert spec.args[0][0].equals(Var(_js_expr="message")) assert spec.args[0][0].equals(Var(_js_expr="function"))
assert spec.args[0][1].equals(LiteralVar.create("message")) assert spec.args[0][1].equals(
assert format.format_event(spec) == 'Event("_alert", {message:"message"})' Var('(() => ((window["alert"]("message"))))', _var_type=Callable)
)
assert (
format.format_event(spec)
== 'Event("_call_function", {function:(() => ((window["alert"]("message"))))})'
)
spec = event.window_alert(Var(_js_expr="message")) spec = event.window_alert(Var(_js_expr="message"))
assert format.format_event(spec) == 'Event("_alert", {message:message})' assert (
format.format_event(spec)
== 'Event("_call_function", {function:(() => ((window["alert"](message))))})'
)
def test_set_focus(): def test_set_focus():

View File

@ -3404,3 +3404,10 @@ def test_fallback_pickle():
state3._g = (i for i in range(10)) state3._g = (i for i in range(10))
pk3 = state3._serialize() pk3 = state3._serialize()
assert len(pk3) == 0 assert len(pk3) == 0
def test_typed_state() -> None:
class TypedState(rx.State):
field: rx.Field[str] = rx.field("")
_ = TypedState(field="str")