add type hinting to events

This commit is contained in:
Khaleel Al-Adhami 2024-10-09 18:43:13 -07:00
parent 7a971e5842
commit e745671d86
28 changed files with 204 additions and 117 deletions

View File

@ -2,11 +2,11 @@
from __future__ import annotations from __future__ import annotations
from typing import Dict, List, Union 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 from reflex.event import EventChain, EventHandler, identity_event
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[lambda data: [data]] on_paste: EventHandler[identity_event(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,6 @@ 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
from reflex.vars import VarData from reflex.vars import VarData
from reflex.vars.base import Var from reflex.vars.base import Var
@ -45,9 +44,6 @@ class DebounceInput(Component):
# The element to wrap # The element to wrap
element: Var[Type[Component]] element: Var[Type[Component]]
# Fired when the input value changes
on_change: EventHandler[lambda e0: [e0.value]]
@classmethod @classmethod
def create(cls, *children: Component, **props: Any) -> Component: def create(cls, *children: Component, **props: Any) -> Component:
"""Create a DebounceInput component. """Create a DebounceInput component.
@ -123,6 +119,8 @@ class DebounceInput(Component):
), ),
) )
print(f"{props=}")
component = super().create(**props) component = super().create(**props)
component._get_style = child._get_style component._get_style = child._get_style
component.event_triggers.update(child.event_triggers) component.event_triggers.update(child.event_triggers)

View File

@ -3,12 +3,12 @@
from __future__ import annotations from __future__ import annotations
from enum import Enum from enum import Enum
from typing import Any, Dict, List, Literal, Optional, Union from typing import Any, 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.components.literals import LiteralRowMarker from reflex.components.literals import LiteralRowMarker
from reflex.event import EventHandler, empty_event from reflex.event import EventHandler, empty_event, identity_event
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
@ -223,13 +223,13 @@ 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[lambda pos: [pos]] on_cell_activated: EventHandler[identity_event(Tuple[int, int])]
# Fired when a cell is clicked. # Fired when a cell is clicked.
on_cell_clicked: EventHandler[lambda pos: [pos]] on_cell_clicked: EventHandler[identity_event(Tuple[int, int])]
# Fired when a cell is right-clicked. # Fired when a cell is right-clicked.
on_cell_context_menu: EventHandler[lambda pos: [pos]] on_cell_context_menu: EventHandler[identity_event(Tuple[int, int])]
# Fired when a cell is edited. # Fired when a cell is edited.
on_cell_edited: EventHandler[on_edit_spec] on_cell_edited: EventHandler[on_edit_spec]
@ -244,16 +244,16 @@ class DataEditor(NoSSRComponent):
on_group_header_renamed: EventHandler[lambda idx, val: [idx, val]] on_group_header_renamed: EventHandler[lambda idx, val: [idx, val]]
# Fired when a header is clicked. # Fired when a header is clicked.
on_header_clicked: EventHandler[lambda pos: [pos]] on_header_clicked: EventHandler[identity_event(Tuple[int, int])]
# Fired when a header is right-clicked. # Fired when a header is right-clicked.
on_header_context_menu: EventHandler[lambda pos: [pos]] on_header_context_menu: EventHandler[identity_event(Tuple[int, int])]
# Fired when a header menu item is clicked. # Fired when a header menu item is clicked.
on_header_menu_click: EventHandler[lambda col, pos: [col, pos]] on_header_menu_click: EventHandler[lambda col, pos: [col, pos]]
# Fired when an item is hovered. # Fired when an item is hovered.
on_item_hovered: EventHandler[lambda pos: [pos]] on_item_hovered: EventHandler[identity_event(Tuple[int, int])]
# Fired when a selection is deleted. # Fired when a selection is deleted.
on_delete: EventHandler[lambda selection: [selection]] on_delete: EventHandler[lambda selection: [selection]]

View File

@ -3,7 +3,7 @@
from __future__ import annotations from __future__ import annotations
from hashlib import md5 from hashlib import md5
from typing import Any, Dict, Iterator, Set, Union from typing import Any, Dict, Iterator, Set, Tuple, Union
from jinja2 import Environment from jinja2 import Environment
@ -102,6 +102,15 @@ class Fieldset(Element):
name: Var[Union[str, int, bool]] name: Var[Union[str, int, bool]]
def on_submit_event_spec() -> Tuple[Var[Dict[str, Any]]]:
"""Event handler spec for the on_submit event.
Returns:
The event handler spec.
"""
return (FORM_DATA,)
class Form(BaseHTML): class Form(BaseHTML):
"""Display the form element.""" """Display the form element."""
@ -141,7 +150,7 @@ class Form(BaseHTML):
handle_submit_unique_name: Var[str] handle_submit_unique_name: Var[str]
# Fired when the form is submitted # Fired when the form is submitted
on_submit: EventHandler[lambda e0: [FORM_DATA]] on_submit: EventHandler[on_submit_event_spec]
@classmethod @classmethod
def create(cls, *children, **props): def create(cls, *children, **props):

View File

@ -4,7 +4,7 @@ import dataclasses
from typing import List, Optional from typing import List, Optional
from reflex.components.component import Component, NoSSRComponent from reflex.components.component import Component, NoSSRComponent
from reflex.event import EventHandler from reflex.event import EventHandler, identity_event
from reflex.utils.imports import ImportDict from reflex.utils.imports import ImportDict
from reflex.vars.base import Var from reflex.vars.base import Var
@ -93,7 +93,7 @@ class Moment(NoSSRComponent):
tz: Var[str] tz: Var[str]
# Fires when the date changes. # Fires when the date changes.
on_change: EventHandler[lambda date: [date]] on_change: EventHandler[identity_event(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 __future__ import annotations from __future__ import annotations
from typing import Any, List, Literal, Optional, Union from typing import Any, List, Literal, Optional, Tuple, Union
from reflex.components.component import Component, ComponentNamespace from reflex.components.component import Component, ComponentNamespace
from reflex.components.core.colors import color from reflex.components.core.colors import color
@ -71,6 +71,18 @@ class AccordionComponent(RadixPrimitiveComponent):
return ["color_scheme", "variant"] return ["color_scheme", "variant"]
def on_value_change(value: Var[str | List[str]]) -> Tuple[Var[str | List[str]]]:
"""Handle the on_value_change event.
Args:
value: The value of the event.
Returns:
The value of the event.
"""
return (value,)
class AccordionRoot(AccordionComponent): class AccordionRoot(AccordionComponent):
"""An accordion component.""" """An accordion component."""
@ -114,7 +126,7 @@ class AccordionRoot(AccordionComponent):
_valid_children: List[str] = ["AccordionItem"] _valid_children: List[str] = ["AccordionItem"]
# Fired when the opened the accordions changes. # Fired when the opened the accordions changes.
on_value_change: EventHandler[lambda e0: [e0]] on_value_change: EventHandler[on_value_change]
def _exclude_props(self) -> list[str]: def _exclude_props(self) -> list[str]:
return super()._exclude_props() + [ return super()._exclude_props() + [

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 from reflex.event import EventHandler, empty_event, identity_event
from reflex.utils import console from reflex.utils import console
from reflex.vars.base import Var from reflex.vars.base import Var
@ -61,7 +61,7 @@ class DrawerRoot(DrawerComponent):
preventScrollRestoration: Var[bool] preventScrollRestoration: Var[bool]
# Fires when the drawer is opened. # Fires when the drawer is opened.
on_open_change: EventHandler[lambda e0: [e0]] on_open_change: EventHandler[identity_event(bool)]
class DrawerTrigger(DrawerComponent): class DrawerTrigger(DrawerComponent):
@ -129,19 +129,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[lambda e0: []] on_open_auto_focus: EventHandler[empty_event]
# Fired when the drawer content is closed. Deprecated. # Fired when the drawer content is closed. Deprecated.
on_close_auto_focus: EventHandler[lambda e0: []] on_close_auto_focus: EventHandler[empty_event]
# Fired when the escape key is pressed. Deprecated. # Fired when the escape key is pressed. Deprecated.
on_escape_key_down: EventHandler[lambda e0: []] on_escape_key_down: EventHandler[empty_event]
# 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[lambda e0: []] on_pointer_down_outside: EventHandler[empty_event]
# Fired when interacting outside the drawer content. Deprecated. # Fired when interacting outside the drawer content. Deprecated.
on_interact_outside: EventHandler[lambda e0: []] on_interact_outside: EventHandler[empty_event]
@classmethod @classmethod
def create(cls, *children, **props): def create(cls, *children, **props):

View File

@ -2,7 +2,7 @@
from __future__ import annotations from __future__ import annotations
from typing import Any, List, Literal from typing import Any, List, Literal, Tuple
from reflex.components.component import Component, ComponentNamespace from reflex.components.component import Component, ComponentNamespace
from reflex.components.radix.primitives.base import RadixPrimitiveComponentWithClassName from reflex.components.radix.primitives.base import RadixPrimitiveComponentWithClassName
@ -19,6 +19,20 @@ class SliderComponent(RadixPrimitiveComponentWithClassName):
library = "@radix-ui/react-slider@^1.1.2" library = "@radix-ui/react-slider@^1.1.2"
def on_value_event_spec(
value: Var[List[int]],
) -> Tuple[Var[List[int]]]:
"""Event handler spec for the value event.
Args:
value: The value of the event.
Returns:
The event handler spec.
"""
return (value,) # type: ignore
class SliderRoot(SliderComponent): class SliderRoot(SliderComponent):
"""The Slider component comtaining all slider parts.""" """The Slider component comtaining all slider parts."""
@ -48,10 +62,10 @@ class SliderRoot(SliderComponent):
min_steps_between_thumbs: Var[int] min_steps_between_thumbs: Var[int]
# Fired when the value of a thumb changes. # Fired when the value of a thumb changes.
on_value_change: EventHandler[lambda e0: [e0]] on_value_change: EventHandler[on_value_event_spec]
# Fired when a thumb is released. # Fired when a thumb is released.
on_value_commit: EventHandler[lambda e0: [e0]] on_value_commit: EventHandler[on_value_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 from reflex.event import EventHandler, empty_event, identity_event
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[lambda e0: [e0]] on_open_change: EventHandler[identity_event(bool)]
class AlertDialogTrigger(RadixThemesTriggerComponent): class AlertDialogTrigger(RadixThemesTriggerComponent):
@ -43,13 +43,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[lambda e0: [e0]] on_open_auto_focus: EventHandler[empty_event]
# Fired when the dialog is closed. # Fired when the dialog is closed.
on_close_auto_focus: EventHandler[lambda e0: [e0]] on_close_auto_focus: EventHandler[empty_event]
# Fired when the escape key is pressed. # Fired when the escape key is pressed.
on_escape_key_down: EventHandler[lambda e0: [e0]] on_escape_key_down: EventHandler[empty_event]
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 from reflex.event import EventHandler, identity_event
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[lambda e0: [e0]] on_change: EventHandler[identity_event(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[lambda e0: [e0]] on_change: EventHandler[identity_event(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 List, 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.event import EventHandler from reflex.event import EventHandler, empty_event, identity_event
from reflex.vars.base import Var from reflex.vars.base import Var
from ..base import ( from ..base import (
@ -24,7 +24,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[lambda e0: [e0]] on_open_change: EventHandler[identity_event(bool)]
class ContextMenuTrigger(RadixThemesComponent): class ContextMenuTrigger(RadixThemesComponent):
@ -64,19 +64,19 @@ class ContextMenuContent(RadixThemesComponent):
avoid_collisions: Var[bool] avoid_collisions: Var[bool]
# Fired when the context menu is closed. # Fired when the context menu is closed.
on_close_auto_focus: EventHandler[lambda e0: [e0]] on_close_auto_focus: EventHandler[empty_event]
# Fired when the escape key is pressed. # Fired when the escape key is pressed.
on_escape_key_down: EventHandler[lambda e0: [e0]] on_escape_key_down: EventHandler[empty_event]
# 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[lambda e0: [e0]] on_pointer_down_outside: EventHandler[empty_event]
# Fired when focus moves outside the context menu. # Fired when focus moves outside the context menu.
on_focus_outside: EventHandler[lambda e0: [e0]] on_focus_outside: EventHandler[empty_event]
# Fired when interacting outside the context menu. # Fired when interacting outside the context menu.
on_interact_outside: EventHandler[lambda e0: [e0]] on_interact_outside: EventHandler[empty_event]
class ContextMenuSub(RadixThemesComponent): class ContextMenuSub(RadixThemesComponent):
@ -107,16 +107,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[lambda e0: [e0]] on_escape_key_down: EventHandler[empty_event]
# 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[lambda e0: [e0]] on_pointer_down_outside: EventHandler[empty_event]
# Fired when focus moves outside the context menu. # Fired when focus moves outside the context menu.
on_focus_outside: EventHandler[lambda e0: [e0]] on_focus_outside: EventHandler[empty_event]
# Fired when interacting outside the context menu. # Fired when interacting outside the context menu.
on_interact_outside: EventHandler[lambda e0: [e0]] on_interact_outside: EventHandler[empty_event]
class ContextMenuItem(RadixThemesComponent): class ContextMenuItem(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 from reflex.event import EventHandler, empty_event, identity_event
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[lambda e0: [e0]] on_open_change: EventHandler[identity_event(bool)]
class DialogTrigger(RadixThemesTriggerComponent): class DialogTrigger(RadixThemesTriggerComponent):
@ -47,19 +47,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[lambda e0: [e0]] on_open_auto_focus: EventHandler[empty_event]
# Fired when the dialog is closed. # Fired when the dialog is closed.
on_close_auto_focus: EventHandler[lambda e0: [e0]] on_close_auto_focus: EventHandler[empty_event]
# Fired when the escape key is pressed. # Fired when the escape key is pressed.
on_escape_key_down: EventHandler[lambda e0: [e0]] on_escape_key_down: EventHandler[empty_event]
# Fired when the pointer is down outside the dialog. # Fired when the pointer is down outside the dialog.
on_pointer_down_outside: EventHandler[lambda e0: [e0]] on_pointer_down_outside: EventHandler[empty_event]
# Fired when the pointer interacts outside the dialog. # Fired when the pointer interacts outside the dialog.
on_interact_outside: EventHandler[lambda e0: [e0]] on_interact_outside: EventHandler[empty_event]
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 from reflex.event import EventHandler, empty_event, identity_event
from reflex.vars.base import Var from reflex.vars.base import Var
from ..base import ( from ..base import (
@ -50,7 +50,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[lambda e0: [e0]] on_open_change: EventHandler[identity_event(bool)]
class DropdownMenuTrigger(RadixThemesTriggerComponent): class DropdownMenuTrigger(RadixThemesTriggerComponent):
@ -120,19 +120,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[lambda e0: [e0]] on_close_auto_focus: EventHandler[empty_event]
# Fired when the escape key is pressed. # Fired when the escape key is pressed.
on_escape_key_down: EventHandler[lambda e0: [e0]] on_escape_key_down: EventHandler[empty_event]
# Fired when the pointer is down outside the dialog. # Fired when the pointer is down outside the dialog.
on_pointer_down_outside: EventHandler[lambda e0: [e0]] on_pointer_down_outside: EventHandler[empty_event]
# Fired when focus moves outside the dialog. # Fired when focus moves outside the dialog.
on_focus_outside: EventHandler[lambda e0: [e0]] on_focus_outside: EventHandler[empty_event]
# Fired when the pointer interacts outside the dialog. # Fired when the pointer interacts outside the dialog.
on_interact_outside: EventHandler[lambda e0: [e0]] on_interact_outside: EventHandler[empty_event]
class DropdownMenuSubTrigger(RadixThemesTriggerComponent): class DropdownMenuSubTrigger(RadixThemesTriggerComponent):
@ -164,7 +164,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[lambda e0: [e0]] on_open_change: EventHandler[identity_event(bool)]
class DropdownMenuSubContent(RadixThemesComponent): class DropdownMenuSubContent(RadixThemesComponent):
@ -205,16 +205,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[lambda e0: [e0]] on_escape_key_down: EventHandler[empty_event]
# Fired when the pointer is down outside the dialog. # Fired when the pointer is down outside the dialog.
on_pointer_down_outside: EventHandler[lambda e0: [e0]] on_pointer_down_outside: EventHandler[empty_event]
# Fired when focus moves outside the dialog. # Fired when focus moves outside the dialog.
on_focus_outside: EventHandler[lambda e0: [e0]] on_focus_outside: EventHandler[empty_event]
# Fired when the pointer interacts outside the dialog. # Fired when the pointer interacts outside the dialog.
on_interact_outside: EventHandler[lambda e0: [e0]] on_interact_outside: EventHandler[empty_event]
class DropdownMenuItem(RadixThemesComponent): class DropdownMenuItem(RadixThemesComponent):
@ -240,7 +240,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[lambda e0: []] on_select: EventHandler[empty_event]
class DropdownMenuSeparator(RadixThemesComponent): class DropdownMenuSeparator(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 from reflex.event import EventHandler, identity_event
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[lambda e0: [e0]] on_open_change: EventHandler[identity_event(bool)]
class HoverCardTrigger(RadixThemesTriggerComponent): class HoverCardTrigger(RadixThemesTriggerComponent):

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 from reflex.event import EventHandler, empty_event, identity_event
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[lambda e0: [e0]] on_open_change: EventHandler[identity_event(bool)]
class PopoverTrigger(RadixThemesTriggerComponent): class PopoverTrigger(RadixThemesTriggerComponent):
@ -59,22 +59,22 @@ class PopoverContent(elements.Div, RadixThemesComponent):
avoid_collisions: Var[bool] avoid_collisions: Var[bool]
# Fired when the dialog is opened. # Fired when the dialog is opened.
on_open_auto_focus: EventHandler[lambda e0: [e0]] on_open_auto_focus: EventHandler[empty_event]
# Fired when the dialog is closed. # Fired when the dialog is closed.
on_close_auto_focus: EventHandler[lambda e0: [e0]] on_close_auto_focus: EventHandler[empty_event]
# Fired when the escape key is pressed. # Fired when the escape key is pressed.
on_escape_key_down: EventHandler[lambda e0: [e0]] on_escape_key_down: EventHandler[empty_event]
# Fired when the pointer is down outside the dialog. # Fired when the pointer is down outside the dialog.
on_pointer_down_outside: EventHandler[lambda e0: [e0]] on_pointer_down_outside: EventHandler[empty_event]
# Fired when focus moves outside the dialog. # Fired when focus moves outside the dialog.
on_focus_outside: EventHandler[lambda e0: [e0]] on_focus_outside: EventHandler[empty_event]
# Fired when the pointer interacts outside the dialog. # Fired when the pointer interacts outside the dialog.
on_interact_outside: EventHandler[lambda e0: [e0]] on_interact_outside: EventHandler[empty_event]
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 from reflex.event import EventHandler, identity_event
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[lambda e0: [e0]] on_value_change: EventHandler[identity_event(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 from reflex.event import EventHandler, identity_event
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[lambda e0: [e0]] on_change: EventHandler[identity_event(str)]
class RadioGroupItem(RadixThemesComponent): class RadioGroupItem(RadixThemesComponent):

View File

@ -3,7 +3,7 @@
from __future__ import annotations from __future__ import annotations
from types import SimpleNamespace from types import SimpleNamespace
from typing import List, Literal, Union from typing import List, Literal, Tuple, Union
from reflex.components.core.breakpoints import Responsive from reflex.components.core.breakpoints import Responsive
from reflex.event import EventHandler from reflex.event import EventHandler
@ -12,6 +12,18 @@ from reflex.vars.base import Var
from ..base import LiteralAccentColor, RadixThemesComponent from ..base import LiteralAccentColor, RadixThemesComponent
def on_value_change(value: Var[str | List[str]]) -> Tuple[Var[str | List[str]]]:
"""Handle the on_value_change event.
Args:
value: The value of the event.
Returns:
The value of the event.
"""
return (value,)
class SegmentedControlRoot(RadixThemesComponent): class SegmentedControlRoot(RadixThemesComponent):
"""Root element for a SegmentedControl component.""" """Root element for a SegmentedControl component."""
@ -39,7 +51,7 @@ class SegmentedControlRoot(RadixThemesComponent):
value: Var[Union[str, List[str]]] value: Var[Union[str, List[str]]]
# Handles the `onChange` event for the SegmentedControl component. # Handles the `onChange` event for the SegmentedControl component.
on_change: EventHandler[lambda e0: [e0]] on_change: EventHandler[on_value_change]
_rename_props = {"onChange": "onValueChange"} _rename_props = {"onChange": "onValueChange"}

View File

@ -5,6 +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.vars.base import Var from reflex.vars.base import Var
from ..base import ( from ..base import (
@ -47,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[lambda e0: [e0]] on_change: rx.EventHandler[identity_event(str)]
# Fired when the select is opened or closed. # Fired when the select is opened or closed.
on_open_change: rx.EventHandler[lambda e0: [e0]] on_open_change: rx.EventHandler[identity_event(bool)]
class SelectTrigger(RadixThemesComponent): class SelectTrigger(RadixThemesComponent):
@ -103,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[lambda e0: [e0]] on_close_auto_focus: rx.EventHandler[empty_event]
# Fired when the escape key is pressed. # Fired when the escape key is pressed.
on_escape_key_down: rx.EventHandler[lambda e0: [e0]] on_escape_key_down: rx.EventHandler[empty_event]
# 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[lambda e0: [e0]] on_pointer_down_outside: rx.EventHandler[empty_event]
class SelectGroup(RadixThemesComponent): class SelectGroup(RadixThemesComponent):

View File

@ -1,6 +1,6 @@
"""Interactive components provided by @radix-ui/themes.""" """Interactive components provided by @radix-ui/themes."""
from typing import List, Literal, Optional, Union from typing import List, Literal, Optional, Tuple, 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
@ -13,6 +13,20 @@ from ..base import (
) )
def on_value_event_spec(
value: Var[List[int | float]],
) -> Tuple[Var[List[int | float]]]:
"""Event handler spec for the value event.
Args:
value: The value of the event.
Returns:
The event handler spec.
"""
return (value,) # type: ignore
class Slider(RadixThemesComponent): class Slider(RadixThemesComponent):
"""Provides user selection from a range of values.""" """Provides user selection from a range of values."""
@ -64,10 +78,10 @@ class Slider(RadixThemesComponent):
_rename_props = {"onChange": "onValueChange"} _rename_props = {"onChange": "onValueChange"}
# Fired when the value of the slider changes. # Fired when the value of the slider changes.
on_change: EventHandler[lambda e0: [e0]] on_change: EventHandler[on_value_event_spec]
# Fired when a thumb is released after being dragged. # Fired when a thumb is released after being dragged.
on_value_commit: EventHandler[lambda e0: [e0]] on_value_commit: EventHandler[on_value_event_spec]
@classmethod @classmethod
def create( def create(

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 from reflex.event import EventHandler, identity_event
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[lambda checked: [checked]] on_change: EventHandler[identity_event(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 from reflex.event import EventHandler, identity_event
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[lambda e0: [e0]] on_change: EventHandler[identity_event(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 from reflex.event import EventHandler, empty_event, identity_event
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[lambda e0: [e0]] on_open_change: EventHandler[identity_event(bool)]
# Fired when the escape key is pressed. # Fired when the escape key is pressed.
on_escape_key_down: EventHandler[lambda e0: []] on_escape_key_down: EventHandler[empty_event]
# Fired when the pointer is down outside the tooltip. # Fired when the pointer is down outside the tooltip.
on_pointer_down_outside: EventHandler[lambda e0: []] on_pointer_down_outside: EventHandler[empty_event]
@classmethod @classmethod
def create(cls, *children, **props) -> Component: def create(cls, *children, **props) -> Component:

View File

@ -3,7 +3,7 @@
from __future__ import annotations from __future__ import annotations
from reflex.components.component import NoSSRComponent from reflex.components.component import NoSSRComponent
from reflex.event import EventHandler, empty_event from reflex.event import EventHandler, empty_event, identity_event
from reflex.vars.base import Var from reflex.vars.base import Var
@ -58,7 +58,7 @@ class ReactPlayer(NoSSRComponent):
on_progress: EventHandler[lambda progress: [progress]] on_progress: EventHandler[lambda progress: [progress]]
# Callback containing duration of the media, in seconds. # Callback containing duration of the media, in seconds.
on_duration: EventHandler[lambda seconds: [seconds]] on_duration: EventHandler[identity_event(float)]
# Called when media is paused. # Called when media is paused.
on_pause: EventHandler[empty_event] on_pause: EventHandler[empty_event]
@ -70,13 +70,13 @@ class ReactPlayer(NoSSRComponent):
on_buffer_end: EventHandler[empty_event] on_buffer_end: EventHandler[empty_event]
# Called when media seeks with seconds parameter. # Called when media seeks with seconds parameter.
on_seek: EventHandler[lambda seconds: [seconds]] on_seek: EventHandler[identity_event(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[lambda e0: []] on_playback_rate_change: EventHandler[empty_event]
# 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[lambda e0: []] on_playback_quality_change: EventHandler[empty_event]
# 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[empty_event]

View File

@ -17,6 +17,7 @@ from typing import (
Optional, Optional,
Tuple, Tuple,
Type, Type,
TypeVar,
Union, Union,
get_type_hints, get_type_hints,
) )
@ -458,6 +459,31 @@ def empty_event() -> Tuple[()]:
return tuple() # type: ignore return tuple() # type: ignore
T = TypeVar("T")
def identity_event(event_type: Type[T]) -> Callable[[Var[T]], Tuple[Var[T]]]:
"""A helper 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
@dataclasses.dataclass( @dataclasses.dataclass(
init=True, init=True,
frozen=True, frozen=True,

View File

@ -18,6 +18,7 @@ from typing import (
List, List,
Literal, Literal,
Optional, Optional,
Sequence,
Tuple, Tuple,
Type, Type,
Union, Union,
@ -102,14 +103,14 @@ if TYPE_CHECKING:
# ArgsSpec = Callable[[Var], list[Var]] # ArgsSpec = Callable[[Var], list[Var]]
ArgsSpec = ( ArgsSpec = (
Callable[[], List[Var]] Callable[[], Sequence[Var]]
| Callable[[Var], List[Var]] | Callable[[Var], Sequence[Var]]
| Callable[[Var, Var], List[Var]] | Callable[[Var, Var], Sequence[Var]]
| Callable[[Var, Var, Var], List[Var]] | Callable[[Var, Var, Var], Sequence[Var]]
| Callable[[Var, Var, Var, Var], List[Var]] | Callable[[Var, Var, Var, Var], Sequence[Var]]
| Callable[[Var, Var, Var, Var, Var], List[Var]] | Callable[[Var, Var, Var, Var, Var], Sequence[Var]]
| Callable[[Var, Var, Var, Var, Var, Var], List[Var]] | Callable[[Var, Var, Var, Var, Var, Var], Sequence[Var]]
| Callable[[Var, Var, Var, Var, Var, Var, Var], List[Var]] | Callable[[Var, Var, Var, Var, Var, Var, Var], Sequence[Var]]
) )
else: else:
ArgsSpec = Callable[..., List[Any]] ArgsSpec = Callable[..., List[Any]]

View File

@ -1794,7 +1794,7 @@ 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[lambda e0: []] on_c: EventHandler[empty_event]
on_d: EventHandler[empty_event] on_d: EventHandler[empty_event]
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

@ -26,7 +26,7 @@ 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[lambda e0: []] on_c: EventHandler[empty_event]
on_d: EventHandler[empty_event] on_d: EventHandler[empty_event]
custom_component = ReferenceComponent.create() custom_component = ReferenceComponent.create()