redesign error boundary screen (#4329)
* redesign error boundary screen * pyi time * add color * i hate python 3.9
This commit is contained in:
parent
7cf3050da0
commit
a1158cdb1c
@ -2,14 +2,15 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Dict, List, Tuple
|
||||
from typing import Dict, Tuple
|
||||
|
||||
from reflex.compiler.compiler import _compile_component
|
||||
from reflex.components.component import Component
|
||||
from reflex.components.el import div, p
|
||||
from reflex.event import EventHandler
|
||||
from reflex.components.datadisplay.logo import svg_logo
|
||||
from reflex.components.el import a, button, details, div, h2, hr, p, pre, summary
|
||||
from reflex.event import EventHandler, set_clipboard
|
||||
from reflex.state import FrontendEventExceptionState
|
||||
from reflex.vars.base import Var
|
||||
from reflex.vars.function import ArgsFunctionOperation
|
||||
|
||||
|
||||
def on_error_spec(
|
||||
@ -40,38 +41,7 @@ class ErrorBoundary(Component):
|
||||
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_custom_code(self) -> List[str]:
|
||||
"""Add custom Javascript code into the page that contains this component.
|
||||
|
||||
Custom code is inserted at module level, after any imports.
|
||||
|
||||
Returns:
|
||||
The custom code to add.
|
||||
"""
|
||||
fallback_container = div(
|
||||
p("Ooops...Unknown Reflex error has occured:"),
|
||||
p(
|
||||
Var(_js_expr="error.message"),
|
||||
color="red",
|
||||
),
|
||||
p("Please contact the support."),
|
||||
)
|
||||
|
||||
compiled_fallback = _compile_component(fallback_container)
|
||||
|
||||
return [
|
||||
f"""
|
||||
function Fallback({{ error, resetErrorBoundary }}) {{
|
||||
return (
|
||||
{compiled_fallback}
|
||||
);
|
||||
}}
|
||||
"""
|
||||
]
|
||||
fallback_render: Var[Component]
|
||||
|
||||
@classmethod
|
||||
def create(cls, *children, **props):
|
||||
@ -86,6 +56,99 @@ class ErrorBoundary(Component):
|
||||
"""
|
||||
if "on_error" not in props:
|
||||
props["on_error"] = FrontendEventExceptionState.handle_frontend_exception
|
||||
if "fallback_render" not in props:
|
||||
props["fallback_render"] = ArgsFunctionOperation.create(
|
||||
("event_args",),
|
||||
Var.create(
|
||||
div(
|
||||
div(
|
||||
div(
|
||||
h2(
|
||||
"An error occurred while rendering this page.",
|
||||
font_size="1.25rem",
|
||||
font_weight="bold",
|
||||
),
|
||||
p(
|
||||
"This is an error with the application itself.",
|
||||
opacity="0.75",
|
||||
),
|
||||
details(
|
||||
summary("Error message", padding="0.5rem"),
|
||||
div(
|
||||
div(
|
||||
pre(
|
||||
Var(
|
||||
_js_expr="event_args.error.stack",
|
||||
),
|
||||
),
|
||||
padding="0.5rem",
|
||||
width="fit-content",
|
||||
),
|
||||
width="100%",
|
||||
max_height="50vh",
|
||||
overflow="auto",
|
||||
background="#000",
|
||||
color="#fff",
|
||||
border_radius="0.25rem",
|
||||
),
|
||||
button(
|
||||
"Copy",
|
||||
on_click=set_clipboard(
|
||||
Var(_js_expr="event_args.error.stack"),
|
||||
),
|
||||
padding="0.35rem 0.75rem",
|
||||
margin="0.5rem",
|
||||
background="#fff",
|
||||
color="#000",
|
||||
border="1px solid #000",
|
||||
border_radius="0.25rem",
|
||||
font_weight="bold",
|
||||
),
|
||||
),
|
||||
display="flex",
|
||||
flex_direction="column",
|
||||
gap="1rem",
|
||||
max_width="50ch",
|
||||
border="1px solid #888888",
|
||||
border_radius="0.25rem",
|
||||
padding="1rem",
|
||||
),
|
||||
hr(
|
||||
border_color="currentColor",
|
||||
opacity="0.25",
|
||||
),
|
||||
a(
|
||||
div(
|
||||
"Built with ",
|
||||
svg_logo("currentColor"),
|
||||
display="flex",
|
||||
align_items="baseline",
|
||||
justify_content="center",
|
||||
font_family="monospace",
|
||||
gap="0.5rem",
|
||||
),
|
||||
href="https://reflex.dev",
|
||||
),
|
||||
display="flex",
|
||||
flex_direction="column",
|
||||
gap="1rem",
|
||||
),
|
||||
height="100%",
|
||||
width="100%",
|
||||
position="absolute",
|
||||
display="flex",
|
||||
align_items="center",
|
||||
justify_content="center",
|
||||
)
|
||||
),
|
||||
_var_type=Component,
|
||||
)
|
||||
else:
|
||||
props["fallback_render"] = ArgsFunctionOperation.create(
|
||||
("event_args",),
|
||||
props["fallback_render"],
|
||||
_var_type=Component,
|
||||
)
|
||||
return super().create(*children, **props)
|
||||
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
# ------------------- DO NOT EDIT ----------------------
|
||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||
# ------------------------------------------------------
|
||||
from typing import Any, Dict, List, Optional, Tuple, Union, overload
|
||||
from typing import Any, Dict, Optional, Tuple, Union, overload
|
||||
|
||||
from reflex.components.component import Component
|
||||
from reflex.event import BASE_STATE, EventType
|
||||
@ -15,13 +15,12 @@ def on_error_spec(
|
||||
) -> Tuple[Var[str], Var[str]]: ...
|
||||
|
||||
class ErrorBoundary(Component):
|
||||
def add_custom_code(self) -> List[str]: ...
|
||||
@overload
|
||||
@classmethod
|
||||
def create( # type: ignore
|
||||
cls,
|
||||
*children,
|
||||
Fallback_component: Optional[Union[Component, Var[Component]]] = None,
|
||||
fallback_render: Optional[Union[Component, Var[Component]]] = None,
|
||||
style: Optional[Style] = None,
|
||||
key: Optional[Any] = None,
|
||||
id: Optional[Any] = None,
|
||||
@ -57,7 +56,7 @@ class ErrorBoundary(Component):
|
||||
Args:
|
||||
*children: The children of the component.
|
||||
on_error: Fired when the boundary catches an error.
|
||||
Fallback_component: Rendered instead of the children when an error is caught.
|
||||
fallback_render: Rendered instead of the children when an error is caught.
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
|
@ -171,6 +171,14 @@ def cond(condition: Any, c1: Any, c2: Any = None) -> Component | Var:
|
||||
)
|
||||
|
||||
|
||||
@overload
|
||||
def color_mode_cond(light: Component, dark: Component | None = None) -> Component: ... # type: ignore
|
||||
|
||||
|
||||
@overload
|
||||
def color_mode_cond(light: Any, dark: Any = None) -> Var: ...
|
||||
|
||||
|
||||
def color_mode_cond(light: Any, dark: Any = None) -> Var | Component:
|
||||
"""Create a component or Prop based on color_mode.
|
||||
|
||||
|
@ -1,22 +1,23 @@
|
||||
"""A Reflex logo component."""
|
||||
|
||||
from typing import Union
|
||||
|
||||
import reflex as rx
|
||||
|
||||
|
||||
def logo(**props):
|
||||
"""A Reflex logo.
|
||||
def svg_logo(color: Union[str, rx.Var[str]] = rx.color_mode_cond("#110F1F", "white")):
|
||||
"""A Reflex logo SVG.
|
||||
|
||||
Args:
|
||||
**props: The props to pass to the component.
|
||||
color: The color of the logo.
|
||||
|
||||
Returns:
|
||||
The logo component.
|
||||
The Reflex logo SVG.
|
||||
"""
|
||||
|
||||
def logo_path(d):
|
||||
return rx.el.svg.path(
|
||||
d=d,
|
||||
fill=rx.color_mode_cond("#110F1F", "white"),
|
||||
)
|
||||
|
||||
paths = [
|
||||
@ -28,18 +29,30 @@ def logo(**props):
|
||||
"M47.04 4.8799V0.399902H49.28V4.8799H47.04ZM53.76 4.8799V0.399902H56V4.8799H53.76ZM49.28 7.1199V4.8799H53.76V7.1199H49.28ZM47.04 11.5999V7.1199H49.28V11.5999H47.04ZM53.76 11.5999V7.1199H56V11.5999H53.76Z",
|
||||
]
|
||||
|
||||
return rx.el.svg(
|
||||
*[logo_path(d) for d in paths],
|
||||
width="56",
|
||||
height="12",
|
||||
viewBox="0 0 56 12",
|
||||
fill=color,
|
||||
xmlns="http://www.w3.org/2000/svg",
|
||||
)
|
||||
|
||||
|
||||
def logo(**props):
|
||||
"""A Reflex logo.
|
||||
|
||||
Args:
|
||||
**props: The props to pass to the component.
|
||||
|
||||
Returns:
|
||||
The logo component.
|
||||
"""
|
||||
return rx.center(
|
||||
rx.link(
|
||||
rx.hstack(
|
||||
"Built with ",
|
||||
rx.el.svg(
|
||||
*[logo_path(d) for d in paths],
|
||||
width="56",
|
||||
height="12",
|
||||
viewBox="0 0 56 12",
|
||||
fill="none",
|
||||
xmlns="http://www.w3.org/2000/svg",
|
||||
),
|
||||
svg_logo(),
|
||||
text_align="center",
|
||||
align="center",
|
||||
padding="1em",
|
||||
|
@ -899,7 +899,7 @@ def remove_session_storage(key: str) -> EventSpec:
|
||||
)
|
||||
|
||||
|
||||
def set_clipboard(content: str) -> EventSpec:
|
||||
def set_clipboard(content: Union[str, Var[str]]) -> EventSpec:
|
||||
"""Set the text in content in the clipboard.
|
||||
|
||||
Args:
|
||||
|
Loading…
Reference in New Issue
Block a user