BasecoatUI components for htmy.

Tabs

Example:

First panel

First panel content.


Code example:

from htmy import ComponentType, html

from htmui.basecoat.tabs import tab_button, tab_panel, tabs


def example() -> ComponentType:
    panel_1_id = "example-panel-1"
    button_1_id = f"{panel_1_id}-button"
    panel_2_id = "example-panel-2"
    button_2_id = f"{panel_2_id}-button"
    return html.div(
        tabs(
            tab_panel(
                html.div(
                    html.header(html.h2("First panel"), html.p("First panel content.")),
                    class_="card",
                ),
                id=panel_1_id,
                button_id=button_1_id,
                selected=True,
                class_="w-80",
            ),
            tab_panel(
                html.div(
                    html.header(html.h2("Second panel"), html.p("Second panel content.")),
                    class_="card",
                ),
                id=panel_2_id,
                button_id=button_2_id,
                class_="w-80",
            ),
            buttons=(
                tab_button(
                    "First",
                    id=button_1_id,
                    panel_id=panel_1_id,
                    selected=True,
                ),
                tab_button(
                    "Second",
                    id=button_2_id,
                    panel_id=panel_2_id,
                ),
            ),
        )
    )

Component implementation:

For more details, see the BasecoatUI documentation.

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

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

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


def tab_button(
    *children: ComponentType,
    id: str,
    panel_id: str,
    selected: bool = False,
    class_: str | None = None,
) -> ComponentType:
    return html.button(
        *children,
        type="button",
        role="tab",
        id=id,
        aria_controls=panel_id,
        aria_selected="true" if selected else "false",
        tabindex="0",
        class_=class_,
    )


def tab_panel(
    *children: ComponentType,
    id: str,
    button_id: str,
    selected: bool = False,
    class_: str | None = None,
) -> ComponentType:
    return html.div(
        *children,
        role="tabpanel",
        id=id,
        aria_labelledby=button_id,
        tabindex="-1",
        aria_selected="true" if selected else "false",
        hidden=None if selected else "",
        class_=class_,
    )


def tabs(
    *panels: ComponentType,
    buttons: ComponentSequence,
    class_: str | None = None,
    **kwargs: PropertyValue,
) -> ComponentType:
    return html.div(
        html.nav(*buttons, role="tablist", aria_orientation="horizontal", class_="w-full"),
        *panels,
        class_=join_classes("tabs w-full", class_),
        **kwargs,
    )