Toolbar Button

#| '!! shinylive warning !!': |
#|   shinylive does not work in self-contained HTML documents.
#|   Please set `embed-resources: false` in your metadata.
#| standalone: true
#| components: [viewer]
#| viewerHeight: 200

from faicons import icon_svg
from shiny.express import input, render, ui

with ui.card(full_screen=True):
    with ui.card_header():
        "Document Actions"
        with ui.toolbar(align="right"):
            ui.toolbar_input_button(
                id="label_only",
                label="Label Only",
            )
            ui.toolbar_input_button(
                id="icon_and_label",
                label="Icon + Label",
                icon=icon_svg("download"),
                show_label=True,
            )
            ui.toolbar_input_button(
                id="icon_only",
                label="Icon Only",
                icon=icon_svg("floppy-disk"),
            )

    @render.text
    def button_status():
        return f"Buttons clicked - Label: {input.label_only()}, Icon: {input.icon_only()}, Both: {input.icon_and_label()}"
from faicons import icon_svg
from shiny.express import input, render, ui

with ui.card(full_screen=True):
    with ui.card_header():
        "Document Actions"
        with ui.toolbar(align="right"):
            ui.toolbar_input_button(
                id="label_only",
                label="Label Only",
            )
            ui.toolbar_input_button(
                id="icon_and_label",
                label="Icon + Label",
                icon=icon_svg("download"),
                show_label=True,
            )
            ui.toolbar_input_button(
                id="icon_only",
                label="Icon Only",
                icon=icon_svg("floppy-disk"),
            )

    @render.text
    def button_status():
        return f"Buttons clicked - Label: {input.label_only()}, Icon: {input.icon_only()}, Both: {input.icon_and_label()}"
from faicons import icon_svg
from shiny import App, render, ui

app_ui = ui.page_fixed(
    ui.card(
        ui.card_header(
            "Document Actions",
            ui.toolbar(
                ui.toolbar_input_button(
                    id="label_only",
                    label="Label Only",
                ),
                ui.toolbar_input_button(
                    id="icon_and_label",
                    label="Icon + Label",
                    icon=icon_svg("download"),
                    show_label=True,
                ),
                ui.toolbar_input_button(
                    id="icon_only",
                    label="Icon Only",
                    icon=icon_svg("floppy-disk"),
                ),
                align="right",
            ),
        ),
        ui.card_body(
            ui.output_text("button_status"),
        ),
        full_screen=True,
    )
)

def server(input, output, session):
    @render.text
    def button_status():
        return f"Buttons clicked - Label: {input.label_only()}, Icon: {input.icon_only()}, Both: {input.icon_and_label()}"

app = App(app_ui, server)
No matching items

Relevant Functions

  • ui.toolbar_input_button
    ui.toolbar_input_button(id, label, *, icon=None, show_label=MISSING, tooltip=MISSING, disabled=False, border=False, **kwargs)

  • ui.update_toolbar_input_button
    ui.update_toolbar_input_button(id, *, label=None, show_label=None, icon=None, disabled=None, session=None)

  • ui.toolbar
    ui.toolbar(*args, align="right", gap=None, width=None)

No matching items

Details

A toolbar button is a compact button designed for use in toolbars within card headers, footers, and other constrained spaces.

To add a toolbar button to your app:

  1. Add ui.toolbar() to create a toolbar container, typically within ui.card_header() or another compact location.
  2. Inside the toolbar, add ui.toolbar_input_button() with an id and label.
  3. Optionally add an icon parameter. When an icon is provided without show_label=True, only the icon is visible and a tooltip with the label text appears on hover.

The value of a toolbar button is accessible as a reactive value. To access the value:

  1. Use input.<button_id>() (e.g., input.save()) to access the click count. The value is an integer representing the number of times the button has been clicked.

Button appearance

Toolbar buttons are designed to be minimal and space-efficient. By default:

  • When no icon is provided, the label text is shown
  • When an icon is provided, only the icon is shown with a tooltip containing the label text
  • Use show_label=True with an icon to show both the icon and label text
  • Set border=True to add a border around the button
  • Set disabled=True to make the button non-clickable
  • Set tooltip="my custom text here" to set tooltip text to a something other than the label text
  • Set tooltip=False to remove the tooltip entirely

Updating buttons

Use ui.update_toolbar_input_button() to change the button’s appearance from the server:

  • Update the label, icon, show_label, or disabled state
  • You cannot add/remove a border or tooltip after creation
  • Use ui.update_tooltip() to update tooltip text

#| '!! shinylive warning !!': |
#|   shinylive does not work in self-contained HTML documents.
#|   Please set `embed-resources: false` in your metadata.
#| standalone: true
#| components: [viewer]
#| viewerHeight: 300

from faicons import icon_svg
from shiny import App, reactive, render, ui

app_ui = ui.page_fluid(
    ui.card(
        ui.card_header(
            "Document Editor",
            ui.toolbar(
                ui.toolbar_input_button(
                    id="save",
                    label="Save",
                    icon=icon_svg("floppy-disk"),
                ),
                align="right",
            ),
        ),
        ui.card_body(
            ui.input_action_button("toggle_disabled", "Toggle Save Button State"),
            ui.input_action_button("toggle_icon", "Toggle Icon"),
            ui.output_text("status"),
        ),
        full_screen=True,
    ),
    {"class": "vh-100 d-flex justify-content-center align-items-center px-4"},
)

def server(input, output, session):
    @reactive.effect
    @reactive.event(input.toggle_disabled)
    def _():
        # Toggle between enabled and disabled
        current_click = input.toggle_disabled()
        is_disabled = current_click % 2 == 1
        ui.update_toolbar_input_button(
            "save",
            disabled=is_disabled,
            label="Save (Disabled)" if is_disabled else "Save",
        )

    @reactive.effect
    @reactive.event(input.toggle_icon)
    def _():
        # Toggle between two different icons
        current_click = input.toggle_icon()
        if current_click % 2 == 1:
            ui.update_toolbar_input_button(
                "save",
                icon=icon_svg("download"),
                label="Download",
            )
        else:
            ui.update_toolbar_input_button(
                "save",
                icon=icon_svg("floppy-disk"),
                label="Save",
            )

    @render.text
    def status():
        return f"Save button clicked {input.save()} times"

app = App(app_ui, server)
from faicons import icon_svg
from shiny import reactive
from shiny.express import input, render, ui

with ui.card(full_screen=True):
    with ui.card_header():
        "Document Editor"
        with ui.toolbar(align="right"):
            ui.toolbar_input_button(
                id="save",
                label="Save",
                icon=icon_svg("floppy-disk"),
            )

    ui.input_action_button("toggle_disabled", "Toggle Save Button State")
    ui.input_action_button("toggle_icon", "Toggle Icon")

    @render.text
    def status():
        return f"Save button clicked {input.save()} times"

@reactive.effect
@reactive.event(input.toggle_disabled)
def _():
    # Toggle between enabled and disabled
    current_click = input.toggle_disabled()
    is_disabled = current_click % 2 == 1
    ui.update_toolbar_input_button(
        "save",
        disabled=is_disabled,
        label="Save (Disabled)" if is_disabled else "Save",
    )

@reactive.effect
@reactive.event(input.toggle_icon)
def _():
    # Toggle between two different icons
    current_click = input.toggle_icon()
    if current_click % 2 == 1:
        ui.update_toolbar_input_button(
            "save",
            icon=icon_svg("download"),
            label="Download",
        )
    else:
        ui.update_toolbar_input_button(
            "save",
            icon=icon_svg("floppy-disk"),
            label="Save",
        )
from faicons import icon_svg
from shiny import App, reactive, render, ui

app_ui = ui.page_fixed(
    ui.card(
        ui.card_header(
            "Document Editor",
            ui.toolbar(
                ui.toolbar_input_button(
                    id="save",
                    label="Save",
                    icon=icon_svg("floppy-disk"),
                ),
                align="right",
            ),
        ),
        ui.card_body(
            ui.input_action_button("toggle_disabled", "Toggle Save Button State"),
            ui.input_action_button("toggle_icon", "Toggle Icon"),
            ui.output_text("status"),
        ),
        full_screen=True,
    )
)

def server(input, output, session):
    @reactive.effect
    @reactive.event(input.toggle_disabled)
    def _():
        # Toggle between enabled and disabled
        current_click = input.toggle_disabled()
        is_disabled = current_click % 2 == 1
        ui.update_toolbar_input_button(
            "save",
            disabled=is_disabled,
            label="Save (Disabled)" if is_disabled else "Save",
        )

    @reactive.effect
    @reactive.event(input.toggle_icon)
    def _():
        # Toggle between two different icons
        current_click = input.toggle_icon()
        if current_click % 2 == 1:
            ui.update_toolbar_input_button(
                "save",
                icon=icon_svg("download"),
                label="Download",
            )
        else:
            ui.update_toolbar_input_button(
                "save",
                icon=icon_svg("floppy-disk"),
                label="Save",
            )

    @render.text
    def status():
        return f"Save button clicked {input.save()} times"

app = App(app_ui, server)
No matching items

Accessibility

Always provide a meaningful label even when using icon-only buttons. The label is used for screen readers and tooltips, ensuring your app is accessible to all users.

See Also: Toolbar | Action Button