BasecoatUI components for htmy.

Dropdown Menu

Example:


Code example:

from htmy import ComponentType, html

from htmui.basecoat.dropdown_menu import dropdown_menu
from htmui.unstyled import menu


def example() -> ComponentType:
    return dropdown_menu(
        menu.group(
            menu.menu_item(html.span("Commit"), data_label="commit"),
            menu.menu_item(html.span("Pull"), data_label="pull"),
            menu.menu_item(html.span("Push"), data_label="push"),
            id="command-group-1",
            label="Git",
            label_props={"class": "font-semibold"},
        ),
        menu.separator(),
        menu.group(
            menu.menu_item(html.span("Review"), data_label="review"),
            menu.menu_item(html.span("Approve"), data_label="approve", disabled=True),
            menu.menu_item(html.span("Comment"), data_label="comment"),
            id="command-group-2",
            label="Actions",
            label_props={"class": "font-semibold"},
        ),
        button_content="Dropdown menu",
        id="dropdown-example",
    )

Component implementation:

For more details, see the BasecoatUI documentation.

from htmy import ComponentType, PropertyValue, SafeStr, html, join_classes

__version__ = "0.1.0"
__framework__ = "BasecoatUI"
__framework_version__ = "0.3"
__framework_url__ = "https://basecoatui.com/components/dropdown-menu/"


js = SafeStr(
    '<script src="https://cdn.jsdelivr.net/npm/basecoat-css@0.3/dist/js/dropdown-menu.min.js" defer>'
    "</script>"
)


def dropdown_menu(
    *items: ComponentType,
    id: str,
    button_content: ComponentType,
    button_class: str | None = None,
    class_: str | None = None,
    popover_class: str | None = None,
    **kwargs: PropertyValue,
) -> ComponentType:
    menu_id = f"{id}-menu"
    button_id = f"{menu_id}-button"
    return html.div(
        html.button(
            button_content,
            type="button",
            id=button_id,
            aria_controls=menu_id,
            aria_expanded="false",
            aria_haspopup="menu",
            class_="btn" if button_class is None else button_class,
        ),
        html.div(
            html.div(
                *items,
                id=menu_id,
                role="menu",
                aria_labelledby=button_id,
            ),
            data_popover="",
            aria_hidden="true",
            class_="min-w-56" if popover_class is None else popover_class,
        ),
        class_=join_classes("dropdown-menu", class_),
        id=id,
        **kwargs,
    )