reflex-dev / reflex

🕸️ Web apps in pure Python 🐍
https://reflex.dev
Apache License 2.0
20.3k stars 1.17k forks source link

Dialog in Menu #3939

Closed Kastier1 closed 1 month ago

Kastier1 commented 1 month ago

Describe the bug A clear and concise description of what the bug is. When I have a dialog within an menu the dialog will only be open when the menu is open, rendering the dialog unusable.

To Reproduce Steps to reproduce the behavior:

class TestState(rx.State): people: List[Tuple[str]] = [ ("bob", "smith" ), ("jane", "ann"), ("katie", "park"), ("rob", "match") ] edit_dialog_open: bool = False

def set_edit_dialog_open(self, value:bool):
    self.edit_dialog_open = value

def form_field_filled(label: str, value: str, type: str, name: str) -> rx.Component: return rx.form.field( rx.flex( rx.form.label(label), rx.form.control( rx.input(placeholder=value, default_value=value), as_child=True, ), direction="column", spacing="1", ), name=name, width="100%", )

def show_row(person: tuple)-> rx.Component: return rx.table.row( rx.table.cell(person[0]), rx.table.cell(person[1]), rx.table.cell(menu(person)), )

def menu(person:tuple)->rx.Component: return rx.menu.root( rx.menu.trigger(rx.icon("ellipsis-vertical")), rx.menu.content(rx.menu.item(edit_dialog(person))), ),

def edit_dialog(person:tuple)->rx.Component: return rx.dialog.root( rx.dialog.trigger(rx.text("Edit")), rx.dialog.content( rx.vstack( rx.dialog.title(f"Edit Category: "), rx.dialog.description("Edit the categorys's info"), ), rx.flex( rx.form.root( rx.flex( form_field_filled("First Name", person[0], "text", "fname"), form_field_filled( "Last Name", person[1], "text", "lname" ), direction="column", ), rx.flex( rx.dialog.close( rx.button( "Cancel" ), style={"margin-right": "1rem"}, ), rx.form.submit( rx.dialog.close(rx.button("Update person")), as_child=True, ), ), reset_on_submit=False, ), ), ), on_open_change=TestState.set_edit_dialog_open, open=TestState.edit_dialog_open )

@rx.page("/test") def test()->rx.Component: return rx.fragment( rx.table.root( rx.table.header( rx.table.row( rx.table.column_header_cell("First Name"), rx.table.column_header_cell("Last Name"), rx.table.column_header_cell(""), ) ), rx.table.body(rx.foreach(TestState.people, show_row)), ), style={"margin-top": "1rem"}, value="categories", spacing="5", justify="center", min_height="85vh", )



**Expected behavior**
A clear and concise description of what you expected to happen.
The expected behavior is that the menu will close and the dialog will open and be functional

**Screenshots**
If applicable, add screenshots to help explain your problem.

https://github.com/user-attachments/assets/cf633f3b-5aec-4d8d-8f23-77d2e77e9eb5

**Specifics (please complete the following information):**
 - Python Version: Python 3.12.6
 - Reflex Version: reflex-0.5.10/ reflex-0.6.0a1 
 - OS: macOS 14.6.1 (23G93)
 - Browser (Optional): 

**Additional context**
Add any other context about the problem here.
wassafshahzad commented 1 month ago

Could you share the whole code so that I may reproduce this example

Kastier1 commented 1 month ago

@wassafshahzad I updated the original post to include a much more concise example of this that you should be able to use to reproduce easily.

wassafshahzad commented 1 month ago

@wassafshahzad I updated the original post to include a much more concise example of this that you should be able to use to reproduce easily.

@Kastier1 Could you share the link to the original post

Kastier1 commented 1 month ago

@wassafshahzad https://github.com/reflex-dev/reflex/issues/3939 the issue we are currently on, I updated

wassafshahzad commented 1 month ago

@wassafshahzad #3939 the issue we are currently on, I updated

Ok thank you, I sorry i misunderstood

Lendemor commented 1 month ago

@Kastier1 I think the way you are trying to do it doesn't work, but it's expected.

If you set the rx.dialog.root inside the rx.menu.content, the whole dialog (trigger + modal) will only render when rx.menu.content is actually open.

The way to make it work is to place the rx.dialog.root outside of the contextual rx.menu.content (somewhere in your page, anywhere really as long as it's rendered) and control the state of the rx.dialog with the prop open=


class State(rx.State):
    dialog_open = False

@rx.page()
def index():
    return rx.vstack(
        rx.menu.root(
            rx.menu.trigger(rx.button("Open Menu")),
            rx.menu.content(
                rx.menu.item(
                    rx.text("Dialog"), on_click=State.setvar("dialog_open", True)
                ),
            ),
        ),
        rx.dialog.root(
            rx.dialog.content(
                rx.dialog.title("Dialog"),
                rx.text("This is a dialog."),
                rx.dialog.close(
                    rx.button("Close", on_click=State.setvar("dialog_open", False))
                ),
            ),
            open=State.dialog_open,
        ),
    )
tgberkeley commented 1 month ago

Here is an example of a dialog from a menu: https://github.com/orgs/reflex-dev/discussions/2865#discussioncomment-8870738