Add type hinting to dataeditor events (#4210)

This commit is contained in:
Khaleel Al-Adhami 2024-10-21 18:53:51 -07:00 committed by GitHub
parent 3ab750fecd
commit c103ab5e28
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
29 changed files with 342 additions and 71 deletions

View File

@ -12,7 +12,9 @@ from reflex.state import FrontendEventExceptionState
from reflex.vars.base import Var
def on_error_spec(error: Var, info: Var[Dict[str, str]]) -> Tuple[Var[str], Var[str]]:
def on_error_spec(
error: Var[Dict[str, str]], info: Var[Dict[str, str]]
) -> Tuple[Var[str], Var[str]]:
"""The spec for the on_error event handler.
Args:

View File

@ -11,7 +11,7 @@ from reflex.style import Style
from reflex.vars.base import Var
def on_error_spec(
error: Var, info: Var[Dict[str, str]]
error: Var[Dict[str, str]], info: Var[Dict[str, str]]
) -> Tuple[Var[str], Var[str]]: ...
class ErrorBoundary(Component):

View File

@ -40,7 +40,7 @@ class Clipboard(Fragment):
on_mouse_out: Optional[EventType[[]]] = None,
on_mouse_over: Optional[EventType[[]]] = None,
on_mouse_up: Optional[EventType[[]]] = None,
on_paste: Optional[EventType] = None,
on_paste: Optional[EventType[list[tuple[str, str]]]] = None,
on_scroll: Optional[EventType[[]]] = None,
on_unmount: Optional[EventType[[]]] = None,
**props,

View File

@ -5,6 +5,8 @@ from __future__ import annotations
from enum import Enum
from typing import Any, Dict, List, Literal, Optional, Tuple, Union
from typing_extensions import TypedDict
from reflex.base import Base
from reflex.components.component import Component, NoSSRComponent
from reflex.components.literals import LiteralRowMarker
@ -120,6 +122,78 @@ def on_edit_spec(pos, data: dict[str, Any]):
return [pos, data]
class Bounds(TypedDict):
"""The bounds of the group header."""
x: int
y: int
width: int
height: int
class CompatSelection(TypedDict):
"""The selection."""
items: list
class Rectangle(TypedDict):
"""The bounds of the group header."""
x: int
y: int
width: int
height: int
class GridSelectionCurrent(TypedDict):
"""The current selection."""
cell: list[int]
range: Rectangle
rangeStack: list[Rectangle]
class GridSelection(TypedDict):
"""The grid selection."""
current: Optional[GridSelectionCurrent]
columns: CompatSelection
rows: CompatSelection
class GroupHeaderClickedEventArgs(TypedDict):
"""The arguments for the group header clicked event."""
kind: str
group: str
location: list[int]
bounds: Bounds
isEdge: bool
shiftKey: bool
ctrlKey: bool
metaKey: bool
isTouch: bool
localEventX: int
localEventY: int
button: int
buttons: int
scrollEdge: list[int]
class GridCell(TypedDict):
"""The grid cell."""
span: Optional[List[int]]
class GridColumn(TypedDict):
"""The grid column."""
title: str
group: Optional[str]
class DataEditor(NoSSRComponent):
"""The DataEditor Component."""
@ -238,10 +312,12 @@ class DataEditor(NoSSRComponent):
on_group_header_clicked: EventHandler[on_edit_spec]
# Fired when a group header is right-clicked.
on_group_header_context_menu: EventHandler[lambda grp_idx, data: [grp_idx, data]]
on_group_header_context_menu: EventHandler[
identity_event(int, GroupHeaderClickedEventArgs)
]
# Fired when a group header is renamed.
on_group_header_renamed: EventHandler[lambda idx, val: [idx, val]]
on_group_header_renamed: EventHandler[identity_event(str, str)]
# Fired when a header is clicked.
on_header_clicked: EventHandler[identity_event(Tuple[int, int])]
@ -250,16 +326,16 @@ class DataEditor(NoSSRComponent):
on_header_context_menu: EventHandler[identity_event(Tuple[int, int])]
# Fired when a header menu item is clicked.
on_header_menu_click: EventHandler[lambda col, pos: [col, pos]]
on_header_menu_click: EventHandler[identity_event(int, Rectangle)]
# Fired when an item is hovered.
on_item_hovered: EventHandler[identity_event(Tuple[int, int])]
# Fired when a selection is deleted.
on_delete: EventHandler[lambda selection: [selection]]
on_delete: EventHandler[identity_event(GridSelection)]
# Fired when editing is finished.
on_finished_editing: EventHandler[lambda new_value, movement: [new_value, movement]]
on_finished_editing: EventHandler[identity_event(Union[GridCell, None], list[int])]
# Fired when a row is appended.
on_row_appended: EventHandler[empty_event]
@ -268,7 +344,7 @@ class DataEditor(NoSSRComponent):
on_selection_cleared: EventHandler[empty_event]
# Fired when a column is resized.
on_column_resize: EventHandler[lambda col, width: [col, width]]
on_column_resize: EventHandler[identity_event(GridColumn, int)]
def add_imports(self) -> ImportDict:
"""Add imports for the component.

View File

@ -6,6 +6,8 @@
from enum import Enum
from typing import Any, Dict, List, Literal, Optional, Union, overload
from typing_extensions import TypedDict
from reflex.base import Base
from reflex.components.component import NoSSRComponent
from reflex.event import EventType
@ -78,6 +80,54 @@ class DataEditorTheme(Base):
def on_edit_spec(pos, data: dict[str, Any]): ...
class Bounds(TypedDict):
x: int
y: int
width: int
height: int
class CompatSelection(TypedDict):
items: list
class Rectangle(TypedDict):
x: int
y: int
width: int
height: int
class GridSelectionCurrent(TypedDict):
cell: list[int]
range: Rectangle
rangeStack: list[Rectangle]
class GridSelection(TypedDict):
current: Optional[GridSelectionCurrent]
columns: CompatSelection
rows: CompatSelection
class GroupHeaderClickedEventArgs(TypedDict):
kind: str
group: str
location: list[int]
bounds: Bounds
isEdge: bool
shiftKey: bool
ctrlKey: bool
metaKey: bool
isTouch: bool
localEventX: int
localEventY: int
button: int
buttons: int
scrollEdge: list[int]
class GridCell(TypedDict):
span: Optional[List[int]]
class GridColumn(TypedDict):
title: str
group: Optional[str]
class DataEditor(NoSSRComponent):
def add_imports(self) -> ImportDict: ...
def add_hooks(self) -> list[str]: ...
@ -136,24 +186,28 @@ class DataEditor(NoSSRComponent):
autofocus: Optional[bool] = None,
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
on_blur: Optional[EventType[[]]] = None,
on_cell_activated: Optional[EventType] = None,
on_cell_clicked: Optional[EventType] = None,
on_cell_context_menu: Optional[EventType] = None,
on_cell_activated: Optional[EventType[tuple[int, int]]] = None,
on_cell_clicked: Optional[EventType[tuple[int, int]]] = None,
on_cell_context_menu: Optional[EventType[tuple[int, int]]] = None,
on_cell_edited: Optional[EventType] = None,
on_click: Optional[EventType[[]]] = None,
on_column_resize: Optional[EventType] = None,
on_column_resize: Optional[EventType[GridColumn, int]] = None,
on_context_menu: Optional[EventType[[]]] = None,
on_delete: Optional[EventType] = None,
on_delete: Optional[EventType[GridSelection]] = None,
on_double_click: Optional[EventType[[]]] = None,
on_finished_editing: Optional[EventType] = None,
on_finished_editing: Optional[
EventType[Union[GridCell, None], list[int]]
] = None,
on_focus: Optional[EventType[[]]] = None,
on_group_header_clicked: Optional[EventType] = None,
on_group_header_context_menu: Optional[EventType] = None,
on_group_header_renamed: Optional[EventType] = None,
on_header_clicked: Optional[EventType] = None,
on_header_context_menu: Optional[EventType] = None,
on_header_menu_click: Optional[EventType] = None,
on_item_hovered: Optional[EventType] = None,
on_group_header_context_menu: Optional[
EventType[int, GroupHeaderClickedEventArgs]
] = None,
on_group_header_renamed: Optional[EventType[str, str]] = None,
on_header_clicked: Optional[EventType[tuple[int, int]]] = None,
on_header_context_menu: Optional[EventType[tuple[int, int]]] = None,
on_header_menu_click: Optional[EventType[int, Rectangle]] = None,
on_item_hovered: Optional[EventType[tuple[int, int]]] = None,
on_mount: Optional[EventType[[]]] = None,
on_mouse_down: Optional[EventType[[]]] = None,
on_mouse_enter: Optional[EventType[[]]] = None,

View File

@ -58,7 +58,7 @@ class Moment(NoSSRComponent):
autofocus: Optional[bool] = None,
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
on_blur: Optional[EventType[[]]] = None,
on_change: Optional[EventType] = None,
on_change: Optional[EventType[str]] = None,
on_click: Optional[EventType[[]]] = None,
on_context_menu: Optional[EventType[[]]] = None,
on_double_click: Optional[EventType[[]]] = None,

View File

@ -101,7 +101,7 @@ class DrawerRoot(DrawerComponent):
on_mouse_out: Optional[EventType[[]]] = None,
on_mouse_over: Optional[EventType[[]]] = None,
on_mouse_up: Optional[EventType[[]]] = None,
on_open_change: Optional[EventType] = None,
on_open_change: Optional[EventType[bool]] = None,
on_scroll: Optional[EventType[[]]] = None,
on_unmount: Optional[EventType[[]]] = None,
**props,
@ -511,7 +511,7 @@ class Drawer(ComponentNamespace):
on_mouse_out: Optional[EventType[[]]] = None,
on_mouse_over: Optional[EventType[[]]] = None,
on_mouse_up: Optional[EventType[[]]] = None,
on_open_change: Optional[EventType] = None,
on_open_change: Optional[EventType[bool]] = None,
on_scroll: Optional[EventType[[]]] = None,
on_unmount: Optional[EventType[[]]] = None,
**props,

View File

@ -383,7 +383,7 @@ class ColorModeSwitch(Switch):
autofocus: Optional[bool] = None,
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
on_blur: Optional[EventType[[]]] = None,
on_change: Optional[EventType] = None,
on_change: Optional[EventType[bool]] = None,
on_click: Optional[EventType[[]]] = None,
on_context_menu: Optional[EventType[[]]] = None,
on_double_click: Optional[EventType[[]]] = None,

View File

@ -42,7 +42,7 @@ class AlertDialogRoot(RadixThemesComponent):
on_mouse_out: Optional[EventType[[]]] = None,
on_mouse_over: Optional[EventType[[]]] = None,
on_mouse_up: Optional[EventType[[]]] = None,
on_open_change: Optional[EventType] = None,
on_open_change: Optional[EventType[bool]] = None,
on_scroll: Optional[EventType[[]]] = None,
on_unmount: Optional[EventType[[]]] = None,
**props,

View File

@ -116,7 +116,7 @@ class Checkbox(RadixThemesComponent):
autofocus: Optional[bool] = None,
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
on_blur: Optional[EventType[[]]] = None,
on_change: Optional[EventType] = None,
on_change: Optional[EventType[bool]] = None,
on_click: Optional[EventType[[]]] = None,
on_context_menu: Optional[EventType[[]]] = None,
on_double_click: Optional[EventType[[]]] = None,
@ -263,7 +263,7 @@ class HighLevelCheckbox(RadixThemesComponent):
autofocus: Optional[bool] = None,
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
on_blur: Optional[EventType[[]]] = None,
on_change: Optional[EventType] = None,
on_change: Optional[EventType[bool]] = None,
on_click: Optional[EventType[[]]] = None,
on_context_menu: Optional[EventType[[]]] = None,
on_double_click: Optional[EventType[[]]] = None,
@ -407,7 +407,7 @@ class CheckboxNamespace(ComponentNamespace):
autofocus: Optional[bool] = None,
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
on_blur: Optional[EventType[[]]] = None,
on_change: Optional[EventType] = None,
on_change: Optional[EventType[bool]] = None,
on_click: Optional[EventType[[]]] = None,
on_context_menu: Optional[EventType[[]]] = None,
on_double_click: Optional[EventType[[]]] = None,

View File

@ -39,7 +39,7 @@ class ContextMenuRoot(RadixThemesComponent):
on_mouse_out: Optional[EventType[[]]] = None,
on_mouse_over: Optional[EventType[[]]] = None,
on_mouse_up: Optional[EventType[[]]] = None,
on_open_change: Optional[EventType] = None,
on_open_change: Optional[EventType[bool]] = None,
on_scroll: Optional[EventType[[]]] = None,
on_unmount: Optional[EventType[[]]] = None,
**props,

View File

@ -40,7 +40,7 @@ class DialogRoot(RadixThemesComponent):
on_mouse_out: Optional[EventType[[]]] = None,
on_mouse_over: Optional[EventType[[]]] = None,
on_mouse_up: Optional[EventType[[]]] = None,
on_open_change: Optional[EventType] = None,
on_open_change: Optional[EventType[bool]] = None,
on_scroll: Optional[EventType[[]]] = None,
on_unmount: Optional[EventType[[]]] = None,
**props,
@ -382,7 +382,7 @@ class Dialog(ComponentNamespace):
on_mouse_out: Optional[EventType[[]]] = None,
on_mouse_over: Optional[EventType[[]]] = None,
on_mouse_up: Optional[EventType[[]]] = None,
on_open_change: Optional[EventType] = None,
on_open_change: Optional[EventType[bool]] = None,
on_scroll: Optional[EventType[[]]] = None,
on_unmount: Optional[EventType[[]]] = None,
**props,

View File

@ -49,7 +49,7 @@ class DropdownMenuRoot(RadixThemesComponent):
on_mouse_out: Optional[EventType[[]]] = None,
on_mouse_over: Optional[EventType[[]]] = None,
on_mouse_up: Optional[EventType[[]]] = None,
on_open_change: Optional[EventType] = None,
on_open_change: Optional[EventType[bool]] = None,
on_scroll: Optional[EventType[[]]] = None,
on_unmount: Optional[EventType[[]]] = None,
**props,
@ -363,7 +363,7 @@ class DropdownMenuSub(RadixThemesComponent):
on_mouse_out: Optional[EventType[[]]] = None,
on_mouse_over: Optional[EventType[[]]] = None,
on_mouse_up: Optional[EventType[[]]] = None,
on_open_change: Optional[EventType] = None,
on_open_change: Optional[EventType[bool]] = None,
on_scroll: Optional[EventType[[]]] = None,
on_unmount: Optional[EventType[[]]] = None,
**props,

View File

@ -43,7 +43,7 @@ class HoverCardRoot(RadixThemesComponent):
on_mouse_out: Optional[EventType[[]]] = None,
on_mouse_over: Optional[EventType[[]]] = None,
on_mouse_up: Optional[EventType[[]]] = None,
on_open_change: Optional[EventType] = None,
on_open_change: Optional[EventType[bool]] = None,
on_scroll: Optional[EventType[[]]] = None,
on_unmount: Optional[EventType[[]]] = None,
**props,
@ -256,7 +256,7 @@ class HoverCard(ComponentNamespace):
on_mouse_out: Optional[EventType[[]]] = None,
on_mouse_over: Optional[EventType[[]]] = None,
on_mouse_up: Optional[EventType[[]]] = None,
on_open_change: Optional[EventType] = None,
on_open_change: Optional[EventType[bool]] = None,
on_scroll: Optional[EventType[[]]] = None,
on_unmount: Optional[EventType[[]]] = None,
**props,

View File

@ -41,7 +41,7 @@ class PopoverRoot(RadixThemesComponent):
on_mouse_out: Optional[EventType[[]]] = None,
on_mouse_over: Optional[EventType[[]]] = None,
on_mouse_up: Optional[EventType[[]]] = None,
on_open_change: Optional[EventType] = None,
on_open_change: Optional[EventType[bool]] = None,
on_scroll: Optional[EventType[[]]] = None,
on_unmount: Optional[EventType[[]]] = None,
**props,

View File

@ -177,7 +177,7 @@ class RadioCardsRoot(RadixThemesComponent):
on_mouse_up: Optional[EventType[[]]] = None,
on_scroll: Optional[EventType[[]]] = None,
on_unmount: Optional[EventType[[]]] = None,
on_value_change: Optional[EventType] = None,
on_value_change: Optional[EventType[str]] = None,
**props,
) -> "RadioCardsRoot":
"""Create a new component instance.

View File

@ -113,7 +113,7 @@ class RadioGroupRoot(RadixThemesComponent):
autofocus: Optional[bool] = None,
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
on_blur: Optional[EventType[[]]] = None,
on_change: Optional[EventType] = None,
on_change: Optional[EventType[str]] = None,
on_click: Optional[EventType[[]]] = None,
on_context_menu: Optional[EventType[[]]] = None,
on_double_click: Optional[EventType[[]]] = None,

View File

@ -44,7 +44,7 @@ class SelectRoot(RadixThemesComponent):
autofocus: Optional[bool] = None,
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
on_blur: Optional[EventType[[]]] = None,
on_change: Optional[EventType] = None,
on_change: Optional[EventType[str]] = None,
on_click: Optional[EventType[[]]] = None,
on_context_menu: Optional[EventType[[]]] = None,
on_double_click: Optional[EventType[[]]] = None,
@ -57,7 +57,7 @@ class SelectRoot(RadixThemesComponent):
on_mouse_out: Optional[EventType[[]]] = None,
on_mouse_over: Optional[EventType[[]]] = None,
on_mouse_up: Optional[EventType[[]]] = None,
on_open_change: Optional[EventType] = None,
on_open_change: Optional[EventType[bool]] = None,
on_scroll: Optional[EventType[[]]] = None,
on_unmount: Optional[EventType[[]]] = None,
**props,
@ -680,7 +680,7 @@ class HighLevelSelect(SelectRoot):
autofocus: Optional[bool] = None,
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
on_blur: Optional[EventType[[]]] = None,
on_change: Optional[EventType] = None,
on_change: Optional[EventType[str]] = None,
on_click: Optional[EventType[[]]] = None,
on_context_menu: Optional[EventType[[]]] = None,
on_double_click: Optional[EventType[[]]] = None,
@ -693,7 +693,7 @@ class HighLevelSelect(SelectRoot):
on_mouse_out: Optional[EventType[[]]] = None,
on_mouse_over: Optional[EventType[[]]] = None,
on_mouse_up: Optional[EventType[[]]] = None,
on_open_change: Optional[EventType] = None,
on_open_change: Optional[EventType[bool]] = None,
on_scroll: Optional[EventType[[]]] = None,
on_unmount: Optional[EventType[[]]] = None,
**props,
@ -854,7 +854,7 @@ class Select(ComponentNamespace):
autofocus: Optional[bool] = None,
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
on_blur: Optional[EventType[[]]] = None,
on_change: Optional[EventType] = None,
on_change: Optional[EventType[str]] = None,
on_click: Optional[EventType[[]]] = None,
on_context_menu: Optional[EventType[[]]] = None,
on_double_click: Optional[EventType[[]]] = None,
@ -867,7 +867,7 @@ class Select(ComponentNamespace):
on_mouse_out: Optional[EventType[[]]] = None,
on_mouse_over: Optional[EventType[[]]] = None,
on_mouse_up: Optional[EventType[[]]] = None,
on_open_change: Optional[EventType] = None,
on_open_change: Optional[EventType[bool]] = None,
on_scroll: Optional[EventType[[]]] = None,
on_unmount: Optional[EventType[[]]] = None,
**props,

View File

@ -119,7 +119,7 @@ class Switch(RadixThemesComponent):
autofocus: Optional[bool] = None,
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
on_blur: Optional[EventType[[]]] = None,
on_change: Optional[EventType] = None,
on_change: Optional[EventType[bool]] = None,
on_click: Optional[EventType[[]]] = None,
on_context_menu: Optional[EventType[[]]] = None,
on_double_click: Optional[EventType[[]]] = None,

View File

@ -41,7 +41,7 @@ class TabsRoot(RadixThemesComponent):
autofocus: Optional[bool] = None,
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
on_blur: Optional[EventType[[]]] = None,
on_change: Optional[EventType] = None,
on_change: Optional[EventType[str]] = None,
on_click: Optional[EventType[[]]] = None,
on_context_menu: Optional[EventType[[]]] = None,
on_double_click: Optional[EventType[[]]] = None,
@ -340,7 +340,7 @@ class Tabs(ComponentNamespace):
autofocus: Optional[bool] = None,
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
on_blur: Optional[EventType[[]]] = None,
on_change: Optional[EventType] = None,
on_change: Optional[EventType[str]] = None,
on_click: Optional[EventType[[]]] = None,
on_context_menu: Optional[EventType[[]]] = None,
on_double_click: Optional[EventType[[]]] = None,

View File

@ -76,7 +76,7 @@ class Tooltip(RadixThemesComponent):
on_mouse_out: Optional[EventType[[]]] = None,
on_mouse_over: Optional[EventType[[]]] = None,
on_mouse_up: Optional[EventType[[]]] = None,
on_open_change: Optional[EventType] = None,
on_open_change: Optional[EventType[bool]] = None,
on_pointer_down_outside: Optional[EventType[[]]] = None,
on_scroll: Optional[EventType[[]]] = None,
on_unmount: Optional[EventType[[]]] = None,

View File

@ -41,7 +41,7 @@ class Audio(ReactPlayer):
on_context_menu: Optional[EventType[[]]] = None,
on_disable_pip: Optional[EventType[[]]] = None,
on_double_click: Optional[EventType[[]]] = None,
on_duration: Optional[EventType] = None,
on_duration: Optional[EventType[float]] = None,
on_enable_pip: Optional[EventType[[]]] = None,
on_ended: Optional[EventType[[]]] = None,
on_error: Optional[EventType[[]]] = None,
@ -61,7 +61,7 @@ class Audio(ReactPlayer):
on_progress: Optional[EventType] = None,
on_ready: Optional[EventType[[]]] = None,
on_scroll: Optional[EventType[[]]] = None,
on_seek: Optional[EventType] = None,
on_seek: Optional[EventType[float]] = None,
on_start: Optional[EventType[[]]] = None,
on_unmount: Optional[EventType[[]]] = None,
**props,

View File

@ -39,7 +39,7 @@ class ReactPlayer(NoSSRComponent):
on_context_menu: Optional[EventType[[]]] = None,
on_disable_pip: Optional[EventType[[]]] = None,
on_double_click: Optional[EventType[[]]] = None,
on_duration: Optional[EventType] = None,
on_duration: Optional[EventType[float]] = None,
on_enable_pip: Optional[EventType[[]]] = None,
on_ended: Optional[EventType[[]]] = None,
on_error: Optional[EventType[[]]] = None,
@ -59,7 +59,7 @@ class ReactPlayer(NoSSRComponent):
on_progress: Optional[EventType] = None,
on_ready: Optional[EventType[[]]] = None,
on_scroll: Optional[EventType[[]]] = None,
on_seek: Optional[EventType] = None,
on_seek: Optional[EventType[float]] = None,
on_start: Optional[EventType[[]]] = None,
on_unmount: Optional[EventType[[]]] = None,
**props,

View File

@ -41,7 +41,7 @@ class Video(ReactPlayer):
on_context_menu: Optional[EventType[[]]] = None,
on_disable_pip: Optional[EventType[[]]] = None,
on_double_click: Optional[EventType[[]]] = None,
on_duration: Optional[EventType] = None,
on_duration: Optional[EventType[float]] = None,
on_enable_pip: Optional[EventType[[]]] = None,
on_ended: Optional[EventType[[]]] = None,
on_error: Optional[EventType[[]]] = None,
@ -61,7 +61,7 @@ class Video(ReactPlayer):
on_progress: Optional[EventType] = None,
on_ready: Optional[EventType[[]]] = None,
on_scroll: Optional[EventType[[]]] = None,
on_seek: Optional[EventType] = None,
on_seek: Optional[EventType[float]] = None,
on_start: Optional[EventType[[]]] = None,
on_unmount: Optional[EventType[[]]] = None,
**props,

View File

@ -128,7 +128,7 @@ class Editor(NoSSRComponent):
autofocus: Optional[bool] = None,
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
on_blur: Optional[EventType[str]] = None,
on_change: Optional[EventType] = None,
on_change: Optional[EventType[str]] = None,
on_click: Optional[EventType[[]]] = None,
on_context_menu: Optional[EventType[[]]] = None,
on_copy: Optional[EventType[[]]] = None,
@ -136,7 +136,7 @@ class Editor(NoSSRComponent):
on_double_click: Optional[EventType[[]]] = None,
on_focus: Optional[EventType[[]]] = None,
on_input: Optional[EventType[[]]] = None,
on_load: Optional[EventType] = None,
on_load: Optional[EventType[bool]] = None,
on_mount: Optional[EventType[[]]] = None,
on_mouse_down: Optional[EventType[[]]] = None,
on_mouse_enter: Optional[EventType[[]]] = None,
@ -148,8 +148,8 @@ class Editor(NoSSRComponent):
on_paste: Optional[EventType[str, bool]] = None,
on_scroll: Optional[EventType[[]]] = None,
on_unmount: Optional[EventType[[]]] = None,
toggle_code_view: Optional[EventType] = None,
toggle_full_screen: Optional[EventType] = None,
toggle_code_view: Optional[EventType[bool]] = None,
toggle_full_screen: Optional[EventType[bool]] = None,
**props,
) -> "Editor":
"""Create an instance of Editor. No children allowed.

View File

@ -24,7 +24,7 @@ from typing import (
overload,
)
from typing_extensions import ParamSpec, get_args, get_origin
from typing_extensions import ParamSpec, Protocol, get_args, get_origin
from reflex import constants
from reflex.utils import console, format
@ -465,33 +465,97 @@ prevent_default = EventChain(events=[], args_spec=empty_event).prevent_default
T = TypeVar("T")
U = TypeVar("U")
def identity_event(event_type: Type[T]) -> Callable[[Var[T]], Tuple[Var[T]]]:
# 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):
"""Protocol for an identity event return."""
def __call__(self, *values: Var[T]) -> Tuple[Var[T], ...]:
"""Return the input values.
Args:
*values: The values to return.
Returns:
The input values.
"""
return values
@overload
def identity_event(event_type: Type[T], /) -> Callable[[Var[T]], Tuple[Var[T]]]: ... # type: ignore
@overload
def identity_event(
event_type_1: Type[T], event_type2: Type[U], /
) -> Callable[[Var[T], Var[U]], Tuple[Var[T], Var[U]]]: ...
@overload
def identity_event(*event_types: Type[T]) -> IdentityEventReturn[T]: ...
def identity_event(*event_types: Type[T]) -> IdentityEventReturn[T]: # type: ignore
"""A helper function that returns the input event as output.
Args:
event_type: The type of the event.
*event_types: The types of the events.
Returns:
A function that returns the input event as output.
"""
def inner(ev: Var[T]) -> Tuple[Var[T]]:
return (ev,)
def inner(*values: Var[T]) -> Tuple[Var[T], ...]:
return values
inner_type = tuple(Var[event_type] for event_type in event_types)
return_annotation = Tuple[inner_type] # type: ignore
inner.__signature__ = inspect.signature(inner).replace( # type: ignore
parameters=[
inspect.Parameter(
"ev",
f"ev_{i}",
kind=inspect.Parameter.POSITIONAL_OR_KEYWORD,
annotation=Var[event_type],
)
for i, event_type in enumerate(event_types)
],
return_annotation=Tuple[Var[event_type]],
return_annotation=return_annotation,
)
inner.__annotations__["ev"] = Var[event_type]
inner.__annotations__["return"] = Tuple[Var[event_type]]
for i, event_type in enumerate(event_types):
inner.__annotations__[f"ev_{i}"] = Var[event_type]
inner.__annotations__["return"] = return_annotation
return inner

View File

@ -129,7 +129,7 @@ class DrawerSidebar(DrawerRoot):
on_mouse_out: Optional[EventType[[]]] = None,
on_mouse_over: Optional[EventType[[]]] = None,
on_mouse_up: Optional[EventType[[]]] = None,
on_open_change: Optional[EventType] = None,
on_open_change: Optional[EventType[bool]] = None,
on_scroll: Optional[EventType[[]]] = None,
on_unmount: Optional[EventType[[]]] = None,
**props,

View File

@ -16,7 +16,7 @@ from itertools import chain
from multiprocessing import Pool, cpu_count
from pathlib import Path
from types import ModuleType, SimpleNamespace
from typing import Any, Callable, Iterable, Type, get_args
from typing import Any, Callable, Iterable, Type, get_args, get_origin
from reflex.components.component import Component
from reflex.utils import types as rx_types
@ -372,6 +372,53 @@ def _extract_class_props_as_ast_nodes(
return kwargs
def type_to_ast(typ) -> ast.AST:
"""Converts any type annotation into its AST representation.
Handles nested generic types, unions, etc.
Args:
typ: The type annotation to convert.
Returns:
The AST representation of the type annotation.
"""
if typ is type(None):
return ast.Name(id="None")
origin = get_origin(typ)
# Handle plain types (int, str, custom classes, etc.)
if origin is None:
if hasattr(typ, "__name__"):
return ast.Name(id=typ.__name__)
elif hasattr(typ, "_name"):
return ast.Name(id=typ._name)
return ast.Name(id=str(typ))
# Get the base type name (List, Dict, Optional, etc.)
base_name = origin._name if hasattr(origin, "_name") else origin.__name__
# Get type arguments
args = get_args(typ)
# Handle empty type arguments
if not args:
return ast.Name(id=base_name)
# Convert all type arguments recursively
arg_nodes = [type_to_ast(arg) for arg in args]
# Special case for single-argument types (like List[T] or Optional[T])
if len(arg_nodes) == 1:
slice_value = arg_nodes[0]
else:
slice_value = ast.Tuple(elts=arg_nodes, ctx=ast.Load())
return ast.Subscript(
value=ast.Name(id=base_name), slice=ast.Index(value=slice_value), ctx=ast.Load()
)
def _get_parent_imports(func):
_imports = {"reflex.vars": ["Var"]}
for type_hint in inspect.get_annotations(func).values():
@ -430,13 +477,40 @@ def _generate_component_create_functiondef(
def figure_out_return_type(annotation: Any):
if inspect.isclass(annotation) and issubclass(annotation, inspect._empty):
return ast.Name(id="Optional[EventType]")
if not isinstance(annotation, str) and get_origin(annotation) is tuple:
arguments = get_args(annotation)
arguments_without_var = [
get_args(argument)[0] if get_origin(argument) == Var else argument
for argument in arguments
]
# Convert each argument type to its AST representation
type_args = [type_to_ast(arg) for arg in arguments_without_var]
# Join the type arguments with commas for EventType
args_str = ", ".join(ast.unparse(arg) for arg in type_args)
# Create EventType using the joined string
event_type = ast.Name(id=f"EventType[{args_str}]")
# Wrap in Optional
optional_type = ast.Subscript(
value=ast.Name(id="Optional"),
slice=ast.Index(value=event_type),
ctx=ast.Load(),
)
return ast.Name(id=ast.unparse(optional_type))
if isinstance(annotation, str) and annotation.startswith("Tuple["):
inside_of_tuple = annotation.removeprefix("Tuple[").removesuffix("]")
if inside_of_tuple == "()":
return ast.Name(id="Optional[EventType[[]]]")
arguments: list[str] = [""]
arguments = [""]
bracket_count = 0

View File

@ -51,6 +51,7 @@ def LifespanApp():
def context_global(self) -> int:
return lifespan_context_global
@rx.event
def tick(self, date):
pass