This commit is contained in:
Khaleel Al-Adhami 2024-10-21 22:58:55 -07:00
commit 0f1e385a2e
31 changed files with 362 additions and 130 deletions

View File

@ -743,6 +743,7 @@ export const useEventLoop = (
addEvents([
Event(`${exception_state_name}.handle_frontend_exception`, {
stack: error.stack,
component_stack: "",
}),
]);
return false;
@ -754,6 +755,7 @@ export const useEventLoop = (
addEvents([
Event(`${exception_state_name}.handle_frontend_exception`, {
stack: event.reason.stack,
component_stack: "",
}),
]);
return false;

View File

@ -2,16 +2,32 @@
from __future__ import annotations
from typing import List
from typing import Dict, List, Tuple
from reflex.compiler.compiler import _compile_component
from reflex.components.component import Component
from reflex.components.el import div, p
from reflex.constants import Hooks, Imports
from reflex.event import EventChain, EventHandler
from reflex.utils.imports import ImportVar
from reflex.event import EventHandler
from reflex.state import FrontendEventExceptionState
from reflex.vars.base import Var
from reflex.vars.function import FunctionVar
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:
error: The error message.
info: Additional information about the error.
Returns:
The arguments for the event handler.
"""
return (
error.stack,
info.componentStack,
)
class ErrorBoundary(Component):
@ -21,31 +37,13 @@ class ErrorBoundary(Component):
tag = "ErrorBoundary"
# Fired when the boundary catches an error.
on_error: EventHandler[lambda error, info: [error, info]] = Var( # type: ignore
"logFrontendError"
).to(FunctionVar, EventChain)
on_error: EventHandler[on_error_spec]
# Rendered instead of the children when an error is caught.
Fallback_component: Var[Component] = Var(_js_expr="Fallback")._replace(
_var_type=Component
)
def add_imports(self) -> dict[str, list[ImportVar]]:
"""Add imports for the component.
Returns:
The imports to add.
"""
return Imports.EVENTS
def add_hooks(self) -> List[str | Var]:
"""Add hooks for the component.
Returns:
The hooks to add.
"""
return [Hooks.EVENTS, Hooks.FRONTEND_ERRORS]
def add_custom_code(self) -> List[str]:
"""Add custom Javascript code into the page that contains this component.
@ -75,5 +73,20 @@ class ErrorBoundary(Component):
"""
]
@classmethod
def create(cls, *children, **props):
"""Create an ErrorBoundary component.
Args:
*children: The children of the component.
**props: The props of the component.
Returns:
The ErrorBoundary component.
"""
if "on_error" not in props:
props["on_error"] = FrontendEventExceptionState.handle_frontend_exception
return super().create(*children, **props)
error_boundary = ErrorBoundary.create

View File

@ -3,17 +3,18 @@
# ------------------- DO NOT EDIT ----------------------
# This file was generated by `reflex/utils/pyi_generator.py`!
# ------------------------------------------------------
from typing import Any, Dict, List, Optional, Union, overload
from typing import Any, Dict, List, Optional, Tuple, Union, overload
from reflex.components.component import Component
from reflex.event import EventType
from reflex.style import Style
from reflex.utils.imports import ImportVar
from reflex.vars.base import Var
def on_error_spec(
error: Var[Dict[str, str]], info: Var[Dict[str, str]]
) -> Tuple[Var[str], Var[str]]: ...
class ErrorBoundary(Component):
def add_imports(self) -> dict[str, list[ImportVar]]: ...
def add_hooks(self) -> List[str | Var]: ...
def add_custom_code(self) -> List[str]: ...
@overload
@classmethod
@ -31,7 +32,7 @@ class ErrorBoundary(Component):
on_click: Optional[EventType[[]]] = None,
on_context_menu: Optional[EventType[[]]] = None,
on_double_click: Optional[EventType[[]]] = None,
on_error: Optional[EventType] = None,
on_error: Optional[EventType[str, str]] = None,
on_focus: Optional[EventType[[]]] = None,
on_mount: Optional[EventType[[]]] = None,
on_mouse_down: Optional[EventType[[]]] = None,
@ -45,7 +46,7 @@ class ErrorBoundary(Component):
on_unmount: Optional[EventType[[]]] = None,
**props,
) -> "ErrorBoundary":
"""Create the component.
"""Create an ErrorBoundary component.
Args:
*children: The children of the component.
@ -59,7 +60,7 @@ class ErrorBoundary(Component):
**props: The props of the component.
Returns:
The component.
The 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

@ -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

@ -3,11 +3,11 @@
from __future__ import annotations
import enum
from typing import Dict, List, Literal, Optional, Union
from typing import Dict, List, Literal, Optional, Tuple, Union
from reflex.base import Base
from reflex.components.component import Component, NoSSRComponent
from reflex.event import EventHandler
from reflex.event import EventHandler, empty_event, identity_event
from reflex.utils.format import to_camel_case
from reflex.utils.imports import ImportDict, ImportVar
from reflex.vars.base import Var
@ -68,6 +68,35 @@ class EditorOptions(Base):
button_list: Optional[List[Union[List[str], str]]]
def on_blur_spec(e: Var, content: Var[str]) -> Tuple[Var[str]]:
"""A helper function to specify the on_blur event handler.
Args:
e: The event.
content: The content of the editor.
Returns:
A tuple containing the content of the editor.
"""
return (content,)
def on_paste_spec(
e: Var, clean_data: Var[str], max_char_count: Var[bool]
) -> Tuple[Var[str], Var[bool]]:
"""A helper function to specify the on_paste event handler.
Args:
e: The event.
clean_data: The clean data.
max_char_count: The maximum character count.
Returns:
A tuple containing the clean data and the maximum character count.
"""
return (clean_data, max_char_count)
class Editor(NoSSRComponent):
"""A Rich Text Editor component based on SunEditor.
Not every JS prop is listed here (some are not easily usable from python),
@ -178,36 +207,31 @@ class Editor(NoSSRComponent):
disable_toolbar: Var[bool]
# Fired when the editor content changes.
on_change: EventHandler[lambda content: [content]]
on_change: EventHandler[identity_event(str)]
# Fired when the something is inputted in the editor.
on_input: EventHandler[lambda e: [e]]
on_input: EventHandler[empty_event]
# Fired when the editor loses focus.
on_blur: EventHandler[lambda e, content: [content]]
on_blur: EventHandler[on_blur_spec]
# Fired when the editor is loaded.
on_load: EventHandler[lambda reload: [reload]]
# Fired when the editor is resized.
on_resize_editor: EventHandler[lambda height, prev_height: [height, prev_height]]
on_load: EventHandler[identity_event(bool)]
# Fired when the editor content is copied.
on_copy: EventHandler[lambda e, clipboard_data: [clipboard_data]]
on_copy: EventHandler[empty_event]
# Fired when the editor content is cut.
on_cut: EventHandler[lambda e, clipboard_data: [clipboard_data]]
on_cut: EventHandler[empty_event]
# Fired when the editor content is pasted.
on_paste: EventHandler[
lambda e, clean_data, max_char_count: [clean_data, max_char_count]
]
on_paste: EventHandler[on_paste_spec]
# Fired when the code view is toggled.
toggle_code_view: EventHandler[lambda is_code_view: [is_code_view]]
toggle_code_view: EventHandler[identity_event(bool)]
# Fired when the full screen mode is toggled.
toggle_full_screen: EventHandler[lambda is_full_screen: [is_full_screen]]
toggle_full_screen: EventHandler[identity_event(bool)]
def add_imports(self) -> ImportDict:
"""Add imports for the Editor component.

View File

@ -4,7 +4,7 @@
# This file was generated by `reflex/utils/pyi_generator.py`!
# ------------------------------------------------------
import enum
from typing import Any, Dict, List, Literal, Optional, Union, overload
from typing import Any, Dict, List, Literal, Optional, Tuple, Union, overload
from reflex.base import Base
from reflex.components.component import NoSSRComponent
@ -44,6 +44,11 @@ class EditorOptions(Base):
rtl: Optional[bool]
button_list: Optional[List[Union[List[str], str]]]
def on_blur_spec(e: Var, content: Var[str]) -> Tuple[Var[str]]: ...
def on_paste_spec(
e: Var, clean_data: Var[str], max_char_count: Var[bool]
) -> Tuple[Var[str], Var[bool]]: ...
class Editor(NoSSRComponent):
def add_imports(self) -> ImportDict: ...
@overload
@ -122,16 +127,16 @@ class Editor(NoSSRComponent):
class_name: Optional[Any] = None,
autofocus: Optional[bool] = None,
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
on_blur: Optional[EventType] = None,
on_change: Optional[EventType] = None,
on_blur: Optional[EventType[str]] = None,
on_change: Optional[EventType[str]] = None,
on_click: Optional[EventType[[]]] = None,
on_context_menu: Optional[EventType[[]]] = None,
on_copy: Optional[EventType] = None,
on_cut: Optional[EventType] = None,
on_copy: Optional[EventType[[]]] = None,
on_cut: Optional[EventType[[]]] = None,
on_double_click: Optional[EventType[[]]] = None,
on_focus: Optional[EventType[[]]] = None,
on_input: Optional[EventType] = None,
on_load: Optional[EventType] = None,
on_input: 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,
@ -140,12 +145,11 @@ class Editor(NoSSRComponent):
on_mouse_out: Optional[EventType[[]]] = None,
on_mouse_over: Optional[EventType[[]]] = None,
on_mouse_up: Optional[EventType[[]]] = None,
on_paste: Optional[EventType] = None,
on_resize_editor: Optional[EventType] = None,
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

@ -132,16 +132,6 @@ class Hooks(SimpleNamespace):
}
})"""
FRONTEND_ERRORS = f"""
const logFrontendError = (error, info) => {{
if (process.env.NODE_ENV === "production") {{
addEvents([Event("{CompileVars.FRONTEND_EXCEPTION_STATE_FULL}.handle_frontend_exception", {{
stack: error.stack,
}})])
}}
}}
"""
class MemoizationDisposition(enum.Enum):
"""The conditions under which a component should be memoized."""

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

@ -39,6 +39,7 @@ from typing import (
from sqlalchemy.orm import DeclarativeBase
from typing_extensions import Self
from reflex import event
from reflex.config import get_config
from reflex.istate.data import RouterData
from reflex.vars.base import (
@ -2094,7 +2095,8 @@ class State(BaseState):
class FrontendEventExceptionState(State):
"""Substate for handling frontend exceptions."""
def handle_frontend_exception(self, stack: str) -> None:
@event
def handle_frontend_exception(self, stack: str, component_stack: str) -> None:
"""Handle frontend exceptions.
If a frontend exception handler is provided, it will be called.
@ -2102,6 +2104,7 @@ class FrontendEventExceptionState(State):
Args:
stack: The stack trace of the exception.
component_stack: The stack trace of the component where the exception occurred.
"""
app_instance = getattr(prerequisites.get_app(), constants.CompileVars.APP)

View File

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