Page freezes and cannot do anything on page
Describe the bug
We have a drawer with input text box to update a value show on page. When user click an update button in drawer, it'll call an alert dialog to ask user to confirm the updated information. If user click yes, then the data will be updated and show on page.
However, after the drawer and alert dialog is closed, the page freezes and we cannot click anything without refreshing page.
Same issue happens when change drawer into a dialog.
This bug occurs when updating reflex to v0.6.6. Before v0.6.6, the page won't freeze.
We check in developer tool, it seems that on body, the style property pointer-events is still set to none after drawer and alert dialog are closed. It seems to be the root cause.
To Reproduce Steps to reproduce the behavior:
import reflex as rx
class State(rx.State):
"""The app state."""
is_open: bool = False
is_show_alert: bool = False
text: str = ""
input_str: str = ""
@rx.event
def open_drawer(self):
self.is_open = True
@rx.event
def close_drawer(self):
self.is_open = False
@rx.event
def open_confirm_alert(self):
self.is_show_alert = True
@rx.event
def close_confirm_alert(self):
self.is_show_alert = False
@rx.event
def update_text(self):
self.close_drawer()
self.close_confirm_alert()
self.text = self.input_str
def drawer_content():
return rx.drawer.content(
rx.flex(
rx.drawer.close(
rx.button(
"Close",
on_click=State.close_drawer,
)
),
rx.hstack(
rx.input(
on_blur=State.set_input_str,
),
rx.button(
"Save",
on_click=State.open_confirm_alert,
),
),
align_items="start",
direction="column",
),
height="100%",
width="20%",
padding="2em",
background_color=rx.color("grass", 7),
)
def lateral_menu():
return rx.drawer.root(
rx.drawer.trigger(
rx.button(
"Open Drawer",
on_click=State.open_drawer,
)
),
rx.drawer.overlay(),
rx.drawer.portal(drawer_content()),
open=State.is_open,
direction="left",
)
def confirm_alert(yes_event, no_event, show_alert):
return rx.alert_dialog.root(
rx.alert_dialog.content(
rx.alert_dialog.title("Confirm alert"),
rx.alert_dialog.description(
"Are you sure to update text?",
),
rx.flex(
rx.alert_dialog.action(
rx.button("Yes",
on_click=yes_event),
),
rx.alert_dialog.cancel(
rx.button("Cancel",
on_click=no_event),
),
spacing="3",
),
),
open=show_alert,
)
def index() -> rx.Component:
return rx.container(
rx.color_mode.button(position="top-right"),
rx.vstack(
rx.heading(State.text),
lateral_menu(),
confirm_alert(
yes_event=State.update_text,
no_event=State.close_confirm_alert,
show_alert=State.is_show_alert,
),
spacing="5",
justify="center",
min_height="85vh",
),
rx.logo(),
)
app = rx.App()
app.add_page(index)
Expected behavior Page should not freeze.
Screenshots
Specifics (please complete the following information):
- Python Version: v3.11.10
- Reflex Version: v0.6.6
- OS: MacOS
- Browser (Optional): chrome
This appears to be caused by a bug in the frontend library that reflex uses, @radix-ui/themes, that is exposed in the Vaul drawer when used with modal=False and controlled open: https://github.com/emilkowalski/vaul/issues/492
The problem you're seeing is fixed in the upstream v3.1.6. However in reflex v0.6.5 we pinned @radix-ui/themes to <3.1.5 because they introduced 2 regressions: one in scroll area width and one in dialog flickering on close. Until those bugs are fixed, reflex is stuck on the older versions of @radix-ui/themes.
So what can be done to workaround?
--- repro_page_freeze/repro_page_freeze.py.orig 2024-12-13 14:56:51
+++ repro_page_freeze/repro_page_freeze.py 2024-12-13 16:10:32
@@ -1,5 +1,9 @@
import reflex as rx
+fix_pointer_events_hack = rx.Var(
+ "(open) => {!open && window.setTimeout(() => (document.body.style.pointerEvents = 'auto'), 200)}",
+ _var_type=rx.EventChain,
+)
class State(rx.State):
"""The app state."""
\ No newline at end of file
@@ -94,6 +98,7 @@
),
),
open=show_alert,
+ on_open_change=fix_pointer_events_hack,
)
We can use a bit of javascript to reset the CSS after some delay π€· it's not pretty, but it's possible.
Hopefully we'll be able to update our @radix-ui/themes package soon and then the hack can also go away.
Fixed in 0.7.1 now that @radix-ui/themes has been bumped to >3.2.0