merging
This commit is contained in:
commit
97430f1e3a
@ -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;
|
||||
|
@ -2,16 +2,30 @@
|
||||
|
||||
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, 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 +35,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 +71,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
|
||||
|
@ -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, 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.
|
||||
"""
|
||||
...
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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,15 +127,15 @@ 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_blur: Optional[EventType[str]] = None,
|
||||
on_change: Optional[EventType] = 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_input: Optional[EventType[[]]] = None,
|
||||
on_load: Optional[EventType] = None,
|
||||
on_mount: Optional[EventType[[]]] = None,
|
||||
on_mouse_down: Optional[EventType[[]]] = None,
|
||||
@ -140,8 +145,7 @@ 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,
|
||||
|
@ -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."""
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user