Custom menu component.

Installation

Copy the following code into your app directory.

uv

buridan add component menu
Usage
from components.ui.menu import menu
Anatomy

Use the following composition to build a Menu

menu.root( menu.trigger(), menu.portal( menu.positioner( menu.popup( menu.item(), menu.separator(), menu.group( menu.group_label(), menu.item(), ), menu.checkbox_item( menu.checkbox_item_indicator(), ), menu.radio_group( menu.radio_item( menu.radio_item_indicator(), ), ), menu.submenu_root( menu.submenu_trigger(), menu.portal( menu.positioner( menu.popup(), ), ), ), ), ), ), )
Example

A basic dropdown menu that opens when the user clicks a trigger button.

High Level

Uses low-level API to create a menu component.

from components.ui.button import button
from components.ui.menu import menu


def menu_high_level():
    return menu.root(
        menu.trigger(render_=button("Open", variant="outline")),
        menu.portal(
            menu.positioner(
                menu.popup(
                    menu.group(
                        menu.group_label("My Account"),
                        menu.item("Profile"),
                        menu.item("Billing"),
                        menu.item("Settings"),
                    ),
                    menu.separator(),
                    menu.group(
                        menu.item("Team"),
                        menu.submenu_root(
                            menu.submenu_trigger("Invite users"),
                            menu.portal(
                                menu.positioner(
                                    menu.popup(
                                        menu.item("Email"),
                                        menu.item("Message"),
                                        menu.separator(),
                                        menu.item("More..."),
                                    ),
                                    side="right",
                                    align="start",
                                    align_offset=-3,
                                    side_offset=0,
                                ),
                            ),
                        ),
                        menu.item("New Team"),
                    ),
                    menu.separator(),
                    menu.group(
                        menu.item("GitHub"),
                        menu.item("Support"),
                        menu.item("API", disabled=True),
                    ),
                    menu.separator(),
                    menu.group(menu.item("Log out")),
                    class_name="w-40",
                ),
                align="start",
            ),
        ),
    )

Use menu.submenu_root() to nest secondary actions.

from components.ui.button import button
from components.ui.menu import menu


def menu_submenu():
    return menu.root(
        menu.trigger(render_=button("Open", variant="outline")),
        menu.portal(
            menu.positioner(
                menu.popup(
                    menu.group(
                        menu.item("Team"),
                        menu.submenu_root(
                            menu.submenu_trigger("Invite users"),
                            menu.portal(
                                menu.positioner(
                                    menu.popup(
                                        menu.item("Email"),
                                        menu.item("Message"),
                                        menu.submenu_root(
                                            menu.submenu_trigger("More options"),
                                            menu.portal(
                                                menu.positioner(
                                                    menu.popup(
                                                        menu.item("Calendly"),
                                                        menu.item("Slack"),
                                                        menu.separator(),
                                                        menu.item("Webhook"),
                                                    ),
                                                    side="right",
                                                    align="start",
                                                ),
                                            ),
                                        ),
                                        menu.separator(),
                                        menu.item("Advanced..."),
                                    ),
                                    side="right",
                                    align="start",
                                ),
                            ),
                        ),
                        menu.item("New Team"),
                    ),
                ),
                align="start",
            ),
        ),
    )
Checkboxes

Use menu.checkbox_item() for toggles.

from reflex.experimental import ClientStateVar

from components.ui.button import button
from components.ui.menu import menu

show_status_bar = ClientStateVar.create("show_status_bar", True)
show_activity_bar = ClientStateVar.create("show_activity_bar", False)
show_panel = ClientStateVar.create("show_panel", False)


def menu_checkboxes():
    return menu.root(
        menu.trigger(render_=button("Open", variant="outline")),
        menu.portal(
            menu.positioner(
                menu.popup(
                    menu.group(
                        menu.group_label("Appearance"),
                        menu.checkbox_item(
                            "Status Bar",
                            menu.checkbox_item_indicator(),
                            default_checked=show_status_bar.value,
                            on_checked_change=show_status_bar.set_value(
                                ~show_status_bar.value
                            ),
                        ),
                        menu.checkbox_item(
                            "Activity Bar",
                            disabled=True,
                        ),
                        menu.checkbox_item(
                            "Panel",
                            menu.checkbox_item_indicator(),
                            default_checked=show_panel.value,
                            on_checked_change=show_panel.set_value,
                        ),
                    ),
                    class_name="w-40",
                ),
            ),
        ),
    )