Shiny Components

Inputs, outputs and display messages to make your data interactive on every device. Add these components to Shiny Layouts to give your app a navbar, sidebar, cards and more.

Inputs

Inputs allow users to interact with the webpage by clicking a button, entering text, selecting an option, and more.

Outputs

Outputs create a spot on the webpage to display results from the server, such as text, tables, plots, and more.

This
That
And The
Other Thing
This
That
And The
Other Thing
#| standalone: true
#| components: [viewer]
from shiny import App, render, ui

app_ui = ui.page_fluid(
    ui.input_text("x", "", placeholder="Enter text"),
    ui.output_text("txt"),
    {
        "class": "vh-100 d-flex justify-content-center align-items-center px-4 flex-column"
    },
)

def server(input, output, session):
    @output
    @render.text
    def txt():
        return f'x: "{input.x()}"'

app = App(app_ui, server, debug=True)
#| standalone: true
#| components: [viewer]
from shiny import App, render, ui

app_ui = ui.page_fluid(
    ui.input_switch("show_slider", "Show slider", True),
    ui.output_ui("uiElement"),
    {"class": "vh-100 d-flex flex-column pt-4 px-4"},
)

def server(input, output, session):
    @render.ui
    def uiElement():
        if input.show_slider():
            return ui.input_slider("slider", "", min=1, max=10, value=5)

app = App(app_ui, server)
#| standalone: true
#| components: [viewer]
from shiny import App, render, ui

app_ui = ui.page_fluid(
    ui.input_text("x", "", placeholder="Enter text"),
    ui.output_text_verbatim("txt"),
    {
        "class": "vh-100 d-flex justify-content-center align-items-center flex-column px-4"
    },
)

def server(input, output, session):
    @output
    @render.text
    def txt():
        return f'x: "{input.x()}"'

app = App(app_ui, server, debug=True)
No matching items

Display Messages

Provide feedback to your user with notifications, progress bars, and confirmation modals.

#| standalone: true
#| components: [viewer]
from shiny.express import ui

# Set some Shiny page options
ui.page_opts(
    title="Hello Shiny Chat",
    fillable=True,
    fillable_mobile=True,
)

# Create a welcome message
welcome = ui.markdown(
    """
    Hi! This is a simple Shiny `Chat` UI. Enter a message below and I will
    simply repeat it back to you. For more examples, see this
    [folder of examples](https://github.com/posit-dev/py-shiny/tree/main/examples/chat).
    """
)

# Create a chat instance
chat = ui.Chat(
    id="chat",
    messages=[welcome],
)

# Display it
chat.ui()

# Define a callback to run when the user submits a message
@chat.on_user_submit
async def _():
    # Get the chat messages.
    messages = chat.messages()
    # Typically you'd pass messages to an LLM for response generation,
    # but for this example, we'll just echo the user's input
    user = messages[-1]["content"]
    # Append a response to the chat
    await chat.append_message(f"You said: {user}")
#| standalone: true
#| components: [viewer]
from shiny import App, Inputs, Outputs, Session, reactive, ui

app_ui = ui.page_fluid(
    ui.input_action_button("show", "Show modal dialog"),
    {"class": "vh-100 d-flex justify-content-center align-items-center px-4"},
)

def server(input: Inputs, output: Outputs, session: Session):
    @reactive.effect
    @reactive.event(input.show)
    def _():
        m = ui.modal(
            "This is a somewhat important message.",
            easy_close=True,
            footer=None,
        )
        ui.modal_show(m)

app = App(app_ui, server)
#| standalone: true
#| components: [viewer]
from shiny import App, reactive, ui
from pathlib import Path

appdir = Path(__file__).parent
app_ui = ui.page_fillable(
    ui.include_css(appdir / "styles.css"),
    ui.input_action_button("show", "Show Notification"),
    {"class": "vh-100 d-flex justify-content-center align-items-center px-4"},
)

def server(input, output, session):
    ids: list[str] = []
    n: int = 0

    @reactive.effect
    @reactive.event(input.show)
    def _():
        nonlocal ids
        nonlocal n
        # Save the ID for removal later
        id = ui.notification_show("Message " + str(n), duration=None)
        ids.append(id)
        n += 1

    @reactive.effect
    @reactive.event(input.remove)
    def _():
        nonlocal ids
        if ids:
            ui.notification_remove(ids.pop())

app = App(app_ui, server)

## file: styles.css
# shiny-notification-panel { max-width: 100%; }
#| standalone: true
#| components: [viewer]
## file: app.py
import asyncio
from pathlib import Path

from shiny import App, reactive, render, ui

appdir = Path(__file__).parent
app_ui = ui.page_fillable(
    ui.include_css(appdir / "styles.css"),
    ui.input_action_button("button", "Compute"),
    ui.output_text("compute"),
    {"class": "vh-100 d-flex justify-content-center align-items-center px-4"},
)

def server(input, output, session):
    @output
    @render.text
    @reactive.event(input.button)
    async def compute():
        with ui.Progress(min=1, max=15) as p:
            p.set(message="Calculation in progress", detail="This may take a while...")

            for i in range(1, 15):
                p.set(i, message="Computing")
                await asyncio.sleep(0.1)

        return "Done computing!"

app = App(app_ui, server)

## file: styles.css
# shiny-notification-panel { max-width: 100%; }
#| standalone: true
#| components: [viewer]
from shiny import App, render, ui

app_ui = ui.page_fluid(
    ui.tooltip(  
        ui.input_action_button("tooltip", "Show tooltip", class_="btn-primary"),
        {"class": "vh-100 d-flex justify-content-center align-items-center px-4"},
        "A tooltip message",  
        id="btn_tooltip",  
        placement="top",  
    ),
)

def server(input, output, session):
    @render.text
    def text():
        return f"Tooltip state: {input.btn_tooltip()}"  

app = App(app_ui, server)
No matching items