New components library - Native UI

Button

Displays a button or a component that looks like a button.

Installation

Copy the following code into your app directory.

uv

uv run buridan add component button
from components.ui.component import button

Anatomy

Use the following composition to build a Button component.

button()

Examples

Sizes

Use the size prop to change the size of the button.

import reflex as rx

from components.icons.hugeicon import hi
from components.ui.button import button


def button_size() -> rx.Component:
    return rx.el.div(
        rx.el.div(
            button("Extra Small", size="xs", variant="outline"),
            button(
                hi("ArrowUpRight03Icon"),
                size="icon-xs",
                aria_label="Submit",
                variant="outline",
            ),
            class_name="flex items-start gap-2",
        ),
        rx.el.div(
            button("Small", size="sm", variant="outline"),
            button(
                hi("ArrowUpRight03Icon"),
                size="icon-sm",
                aria_label="Submit",
                variant="outline",
            ),
            class_name="flex items-start gap-2",
        ),
        rx.el.div(
            button("Default", variant="outline"),
            button(
                hi("ArrowUpRight03Icon"),
                size="icon",
                aria_label="Submit",
                variant="outline",
            ),
            class_name="flex items-start gap-2",
        ),
        rx.el.div(
            button("Large", variant="outline", size="lg"),
            button(
                hi("ArrowUpRight03Icon"),
                size="icon-lg",
                aria_label="Submit",
                variant="outline",
            ),
            class_name="flex items-start gap-2",
        ),
        class_name="flex flex-col items-start gap-8 sm:flex-row",
    )
from components.ui.button import button


def button_default():
    return button("Button")
from components.ui.button import button


def button_secondary():
    return button("Secondary", variant="secondary")
from components.ui.button import button


def button_outline():
    return button("Outline", variant="outline")
from components.ui.button import button


def button_ghost():
    return button("Ghost", variant="ghost")
from components.ui.button import button


def button_link():
    return button("Link", variant="link")
from components.ui.button import button


def button_destructive():
    return button("Destructive", variant="destructive")
from components.icons.hugeicon import hi
from components.ui.button import button


def button_icon():
    return button(
        hi("CircleArrowUp01Icon", class_name="size-4"),
        variant="outline",
        size="icon",
    )

With Icon

Remember to add the data-icon="inline-start" or data-icon="inline-end" attribute to the icon for the correct spacing.

import reflex as rx

from components.icons.hugeicon import hi
from components.ui.button import button


def button_with_icon() -> rx.Component:
    return rx.el.div(
        button(
            hi("GitBranchIcon", custom_attrs={"data-icon": "inline-start"}),
            "New Branch",
            variant="outline",
        ),
        button(
            "Fork",
            hi("GitForkIcon", custom_attrs={"data-icon": "inline-end"}),
            variant="outline",
        ),
        class_name="flex gap-2",
    )

Rounded

Use the rounded-full class to make the button rounded.

import reflex as rx

from components.icons.hugeicon import hi
from components.ui.button import button


def button_rounded() -> rx.Component:
    return rx.el.div(
        button(
            "Get Started",
            class_name="rounded-full",
        ),
        button(
            hi("ArrowUp02Icon"),
            variant="outline",
            size="icon",
            class_name="rounded-full",
        ),
        class_name="flex gap-2",
    )

Spinner

Render a spinner() component inside the button to show a loading state. Remember to add the data-icon="inline-start" or data-icon="inline-end" attribute to the spinner for the correct spacing.

import reflex as rx

from components.ui.button import button
from components.ui.spinner import spinner


def button_loading() -> rx.Component:
    return rx.el.div(
        button(
            spinner(custom_attrs={"data-icon": "inline-start"}),
            "Generating",
            variant="outline",
        ),
        button(
            "Downloading",
            spinner(custom_attrs={"data-icon": "inline-end"}),
            variant="secondary",
            disabled=True,
        ),
        class_name="flex gap-2",
    )

You can use the button_variants helper function to make a link look like a button.

Do not use button(rx.el.a(...)) for links. The Base UI Button component always applies role="button", which overrides the semantic link role on <a> elements. Use button_variants with a plain rx.el.a tag instead to cleanly generate the necessary classes as a dynamic Reflex Var.

import reflex as rx

from components.ui.button import button_variants


def button_render() -> rx.Component:
    return rx.el.a(
        "Login",
        href="#",
        class_name=button_variants(variant="secondary", size="sm"),
    )

API Reference

Button

The Button component is a wrapper around the button element that adds a variety of styles and functionality.

PropTypeDefault
variant"default" | "outline" | "ghost" | "destructive" | "secondary" | "link""default"
size"default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg""default"