diff --git a/shiny/api-examples/accordion/app-express.py b/shiny/api-examples/accordion/app-express.py
new file mode 100644
index 000000000..10aeb7c00
--- /dev/null
+++ b/shiny/api-examples/accordion/app-express.py
@@ -0,0 +1,30 @@
+from shiny.express import input, render, ui
+
+with ui.card():
+ ui.card_header("Single selction accordion")
+ with ui.accordion(multiple=False, id="acc_single"):
+ with ui.accordion_panel("Section 1"):
+ "Some text for Section 1"
+ with ui.accordion_panel("Section 2"):
+ "More things on Section 2"
+ with ui.accordion_panel("Section 3"):
+ "Another great section"
+
+ @render.text
+ def acc_single_val():
+ return "Selected accordion: " + str(input.acc_single())
+
+
+with ui.card():
+ ui.card_header("Multiple selction accordion")
+ with ui.accordion(multiple=True, id="acc_multiple"):
+ with ui.accordion_panel("Section 1"):
+ "Some text for Section 1"
+ with ui.accordion_panel("Section 2"):
+ "More things on Section 2"
+ with ui.accordion_panel("Section 3"):
+ "Another great section"
+
+ @render.text
+ def acc_multiple_val():
+ return "Selected accordions: " + str(input.acc_multiple())
diff --git a/shiny/api-examples/accordion/app.py b/shiny/api-examples/accordion/app.py
index 5f278f6d6..6f1a95c83 100644
--- a/shiny/api-examples/accordion/app.py
+++ b/shiny/api-examples/accordion/app.py
@@ -22,14 +22,16 @@ def make_items():
app_ui = ui.page_fluid(
- ui.markdown("#### Accordion: (`multiple=False`)"),
- # Provide an id to create a shiny input binding
- ui.accordion(*make_items(), id="acc_single", multiple=False),
- ui.output_text_verbatim("acc_single_val", placeholder=True),
- ui.tags.br(),
- ui.markdown("#### Accordion: (`multiple=True`)"),
- ui.accordion(*make_items(), id="acc_multiple"),
- ui.output_text_verbatim("acc_multiple_val", placeholder=True),
+ ui.card(
+ ui.card_header("Single selection accordion"),
+ ui.accordion(*make_items(), id="acc_single", multiple=False),
+ ui.output_text_verbatim("acc_single_val", placeholder=True),
+ ),
+ ui.card(
+ ui.card_header("Multiple selection accordion"),
+ ui.accordion(*make_items(), id="acc_multiple"),
+ ui.output_text_verbatim("acc_multiple_val", placeholder=True),
+ ),
)
diff --git a/shiny/api-examples/accordion_panel/app-express.py b/shiny/api-examples/accordion_panel/app-express.py
new file mode 100644
index 000000000..c01659714
--- /dev/null
+++ b/shiny/api-examples/accordion_panel/app-express.py
@@ -0,0 +1,12 @@
+from shiny.express import input, render, ui
+
+ui.card_header("Single selection accordion")
+with ui.accordion(multiple=False, id="acc"):
+ for letter in "ABCDE":
+ with ui.accordion_panel(f"Section {letter}"):
+ f"Some narrative for section {letter}"
+
+
+@render.text
+def acc_val():
+ return "input.acc(): " + str(input.acc())
diff --git a/shiny/api-examples/card/app-express.py b/shiny/api-examples/card/app-express.py
new file mode 100644
index 000000000..fb8eb3e70
--- /dev/null
+++ b/shiny/api-examples/card/app-express.py
@@ -0,0 +1,7 @@
+from shiny.express import ui
+
+with ui.card(full_screen=True):
+ ui.card_header("This is the header")
+ ui.p("This is the body")
+ ui.p("This is still the body.")
+ ui.card_footer("This is the footer")
diff --git a/shiny/api-examples/card_footer/app-express.py b/shiny/api-examples/card_footer/app-express.py
new file mode 100644
index 000000000..fb8eb3e70
--- /dev/null
+++ b/shiny/api-examples/card_footer/app-express.py
@@ -0,0 +1,7 @@
+from shiny.express import ui
+
+with ui.card(full_screen=True):
+ ui.card_header("This is the header")
+ ui.p("This is the body")
+ ui.p("This is still the body.")
+ ui.card_footer("This is the footer")
diff --git a/shiny/api-examples/card_header/app-express.py b/shiny/api-examples/card_header/app-express.py
new file mode 100644
index 000000000..fb8eb3e70
--- /dev/null
+++ b/shiny/api-examples/card_header/app-express.py
@@ -0,0 +1,7 @@
+from shiny.express import ui
+
+with ui.card(full_screen=True):
+ ui.card_header("This is the header")
+ ui.p("This is the body")
+ ui.p("This is still the body.")
+ ui.card_footer("This is the footer")
diff --git a/shiny/api-examples/input_action_link/app-express.py b/shiny/api-examples/input_action_link/app-express.py
new file mode 100644
index 000000000..39939d756
--- /dev/null
+++ b/shiny/api-examples/input_action_link/app-express.py
@@ -0,0 +1,20 @@
+import matplotlib.pyplot as plt
+import numpy as np
+
+from shiny import reactive
+from shiny.express import input, render, ui
+
+ui.input_slider("n", "Number of observations", min=0, max=1000, value=500)
+ui.input_action_link("go", "Go!")
+
+
+@render.plot(alt="A histogram")
+# reactive.event() to invalidate the plot when the button is pressed but not when
+# the slider is changed
+@reactive.event(input.go, ignore_none=False)
+def plot():
+ np.random.seed(19680801)
+ x = 100 + 15 * np.random.randn(input.n())
+ fig, ax = plt.subplots()
+ ax.hist(x, bins=30, density=True)
+ return fig
diff --git a/shiny/api-examples/input_checkbox/app-express.py b/shiny/api-examples/input_checkbox/app-express.py
new file mode 100644
index 000000000..1c7e87f7e
--- /dev/null
+++ b/shiny/api-examples/input_checkbox/app-express.py
@@ -0,0 +1,8 @@
+from shiny.express import input, render, ui
+
+ui.input_checkbox("somevalue", "Some value", False)
+
+
+@render.ui
+def value():
+ return input.somevalue()
diff --git a/shiny/api-examples/input_checkbox_group/app-express.py b/shiny/api-examples/input_checkbox_group/app-express.py
new file mode 100644
index 000000000..9f3b9652b
--- /dev/null
+++ b/shiny/api-examples/input_checkbox_group/app-express.py
@@ -0,0 +1,18 @@
+from shiny import req
+from shiny.express import input, render, ui
+
+ui.input_checkbox_group(
+ "colors",
+ "Choose color(s):",
+ {
+ "red": ui.span("Red", style="color: #FF0000;"),
+ "green": ui.span("Green", style="color: #00AA00;"),
+ "blue": ui.span("Blue", style="color: #0000AA;"),
+ },
+)
+
+
+@render.ui
+def val():
+ req(input.colors())
+ return "You chose " + ", ".join(input.colors())
diff --git a/shiny/api-examples/input_date/app-express.py b/shiny/api-examples/input_date/app-express.py
new file mode 100644
index 000000000..bd696beb3
--- /dev/null
+++ b/shiny/api-examples/input_date/app-express.py
@@ -0,0 +1,24 @@
+from datetime import date
+
+from shiny.express import ui
+
+ui.input_date("date1", "Date:", value="2016-02-29")
+# Default value is the date in client's time zone
+ui.input_date("date2", "Date:")
+# value is always yyyy-mm-dd, even if the display format is different
+ui.input_date("date3", "Date:", value="2016-02-29", format="mm/dd/yy")
+# Pass in a Date object
+ui.input_date("date4", "Date:", value=date(2016, 2, 29))
+# Use different language and different first day of week
+ui.input_date("date5", "Date:", language="ru", weekstart=1)
+# Start with decade view instead of default month view
+ui.input_date("date6", "Date:", startview="decade")
+# Disable Mondays and Tuesdays.
+ui.input_date("date7", "Date:", daysofweekdisabled=[1, 2])
+# Disable specific dates.
+ui.input_date(
+ "date8",
+ "Date:",
+ value="2016-02-29",
+ datesdisabled=["2016-03-01", "2016-03-02"],
+)
diff --git a/shiny/api-examples/input_date_range/app-express.py b/shiny/api-examples/input_date_range/app-express.py
new file mode 100644
index 000000000..66f79c5c4
--- /dev/null
+++ b/shiny/api-examples/input_date_range/app-express.py
@@ -0,0 +1,27 @@
+from datetime import date
+
+from shiny.express import ui
+
+ui.input_date_range("daterange1", "Date range:", start="2001-01-01", end="2010-12-31")
+# Default start and end is the current date in the client's time zone
+ui.input_date_range("daterange2", "Date range:")
+# start and end are always specified in yyyy-mm-dd, even if the display
+# format is different
+ui.input_date_range(
+ "daterange3",
+ "Date range:",
+ start="2001-01-01",
+ end="2010-12-31",
+ min="2001-01-01",
+ max="2012-12-21",
+ format="mm/dd/yy",
+ separator=" - ",
+)
+# Pass in Date objects
+ui.input_date_range(
+ "daterange4", "Date range:", start=date(2001, 1, 1), end=date(2010, 12, 31)
+)
+# Use different language and different first day of week
+ui.input_date_range("daterange5", "Date range:", language="de", weekstart=1)
+# Start with decade view instead of default month view
+ui.input_date_range("daterange6", "Date range:", startview="decade")
diff --git a/shiny/api-examples/input_file/app-express.py b/shiny/api-examples/input_file/app-express.py
new file mode 100644
index 000000000..81222e4f7
--- /dev/null
+++ b/shiny/api-examples/input_file/app-express.py
@@ -0,0 +1,48 @@
+import pandas as pd
+
+from shiny import reactive
+from shiny.express import input, render, ui
+from shiny.types import FileInfo
+
+ui.input_file("file1", "Choose CSV File", accept=[".csv"], multiple=False)
+ui.input_checkbox_group(
+ "stats",
+ "Summary Stats",
+ choices=["Row Count", "Column Count", "Column Names"],
+ selected=["Row Count", "Column Count", "Column Names"],
+)
+
+
+@reactive.Calc
+def parsed_file():
+ file: list[FileInfo] | None = input.file1()
+ if file is None:
+ return pd.DataFrame()
+ return pd.read_csv(file[0]["datapath"]) # pyright: ignore[reportUnknownMemberType]
+
+
+@render.table
+def summary():
+ df = parsed_file()
+
+ if df.empty:
+ return pd.DataFrame()
+
+ # Get the row count, column count, and column names of the DataFrame
+ row_count = df.shape[0]
+ column_count = df.shape[1]
+ names = df.columns.tolist()
+ column_names = ", ".join(str(name) for name in names)
+
+ # Create a new DataFrame to display the information
+ info_df = pd.DataFrame(
+ {
+ "Row Count": [row_count],
+ "Column Count": [column_count],
+ "Column Names": [column_names],
+ }
+ )
+
+ # input.stats() is a list of strings; subset the columns based on the selected
+ # checkboxes
+ return info_df.loc[:, input.stats()]
diff --git a/shiny/api-examples/input_numeric/app-express.py b/shiny/api-examples/input_numeric/app-express.py
new file mode 100644
index 000000000..7e06f1c0a
--- /dev/null
+++ b/shiny/api-examples/input_numeric/app-express.py
@@ -0,0 +1,8 @@
+from shiny.express import input, render, ui
+
+ui.input_numeric("obs", "Observations:", 10, min=1, max=100)
+
+
+@render.code
+def value():
+ return input.obs()
diff --git a/shiny/api-examples/input_password/app-express.py b/shiny/api-examples/input_password/app-express.py
new file mode 100644
index 000000000..4366c5303
--- /dev/null
+++ b/shiny/api-examples/input_password/app-express.py
@@ -0,0 +1,11 @@
+from shiny import reactive
+from shiny.express import input, render, ui
+
+ui.input_password("password", "Password:")
+ui.input_action_button("go", "Go")
+
+
+@render.code
+@reactive.event(input.go)
+def value():
+ return input.password()
diff --git a/shiny/api-examples/input_radio_buttons/app-express.py b/shiny/api-examples/input_radio_buttons/app-express.py
new file mode 100644
index 000000000..5354f4134
--- /dev/null
+++ b/shiny/api-examples/input_radio_buttons/app-express.py
@@ -0,0 +1,15 @@
+from shiny.express import input, render, ui
+
+ui.input_radio_buttons(
+ "rb",
+ "Choose one:",
+ {
+ "html": ui.HTML("Red Text"),
+ "text": "Normal text",
+ },
+)
+
+
+@render.express
+def val():
+ "You chose " + input.rb()
diff --git a/shiny/api-examples/input_select/app-express.py b/shiny/api-examples/input_select/app-express.py
new file mode 100644
index 000000000..c45482f0c
--- /dev/null
+++ b/shiny/api-examples/input_select/app-express.py
@@ -0,0 +1,16 @@
+from shiny.express import input, render, ui
+
+ui.input_select(
+ "state",
+ "Choose a state:",
+ {
+ "East Coast": {"NY": "New York", "NJ": "New Jersey", "CT": "Connecticut"},
+ "West Coast": {"WA": "Washington", "OR": "Oregon", "CA": "California"},
+ "Midwest": {"MN": "Minnesota", "WI": "Wisconsin", "IA": "Iowa"},
+ },
+)
+
+
+@render.text
+def value():
+ return "You choose: " + str(input.state())
diff --git a/shiny/api-examples/input_selectize/app-express.py b/shiny/api-examples/input_selectize/app-express.py
new file mode 100644
index 000000000..d58e04154
--- /dev/null
+++ b/shiny/api-examples/input_selectize/app-express.py
@@ -0,0 +1,45 @@
+from html import escape # noqa: F401
+
+from shiny.express import input, render, ui
+
+states = {
+ "East Coast": {"NY": "New York", "NJ": "New Jersey", "CT": "Connecticut"},
+ "West Coast": {"WA": "Washington", "OR": "Oregon", "CA": "California"},
+ "Midwest": {"MN": "Minnesota", "WI": "Wisconsin", "IA": "Iowa"},
+}
+
+ui.input_selectize(
+ "state",
+ "Choose a state:",
+ states,
+ multiple=True,
+)
+
+
+@render.text
+def value():
+ return "You choose: " + str(input.state())
+
+
+ui.input_selectize(
+ "state2",
+ "Selectize Options",
+ states,
+ multiple=True,
+ options=(
+ {
+ "placeholder": "Enter text",
+ "render": ui.js_eval(
+ '{option: function(item, escape) {return "
Select " + escape(item.label) + "
";}}'
+ ),
+ "create": True,
+ }
+ ),
+)
+ui.input_selectize(
+ "state3",
+ "Selectize plugins",
+ states,
+ multiple=True,
+ options={"plugins": ["clear_button"]},
+)
diff --git a/shiny/api-examples/input_selectize/app.py b/shiny/api-examples/input_selectize/app.py
index bc2dd9bd9..23a63d376 100644
--- a/shiny/api-examples/input_selectize/app.py
+++ b/shiny/api-examples/input_selectize/app.py
@@ -17,7 +17,7 @@
),
ui.output_text("value"),
ui.input_selectize(
- "state",
+ "state2",
"Selectize Options",
states,
multiple=True,
@@ -32,7 +32,7 @@
),
),
ui.input_selectize(
- "state",
+ "state3",
"Selectize plugins",
states,
multiple=True,
diff --git a/shiny/api-examples/input_slider/app-express.py b/shiny/api-examples/input_slider/app-express.py
new file mode 100644
index 000000000..e6e701594
--- /dev/null
+++ b/shiny/api-examples/input_slider/app-express.py
@@ -0,0 +1,16 @@
+import matplotlib.pyplot as plt
+import numpy as np
+
+from shiny.express import input, render, ui
+
+ui.input_slider("obs", "Number of bins:", min=10, max=100, value=30)
+
+
+@render.plot
+def distPlot():
+ np.random.seed(19680801)
+ x = 100 + 15 * np.random.randn(437)
+
+ fig, ax = plt.subplots()
+ ax.hist(x, input.obs(), density=True)
+ return fig
diff --git a/shiny/api-examples/input_switch/app-express.py b/shiny/api-examples/input_switch/app-express.py
new file mode 100644
index 000000000..efd623850
--- /dev/null
+++ b/shiny/api-examples/input_switch/app-express.py
@@ -0,0 +1,8 @@
+from shiny.express import input, render, ui
+
+ui.input_switch("somevalue", "Some value", False)
+
+
+@render.text
+def value():
+ return input.somevalue()
diff --git a/shiny/api-examples/input_switch/app.py b/shiny/api-examples/input_switch/app.py
index a438d8195..f05cba431 100644
--- a/shiny/api-examples/input_switch/app.py
+++ b/shiny/api-examples/input_switch/app.py
@@ -2,12 +2,12 @@
app_ui = ui.page_fluid(
ui.input_switch("somevalue", "Some value", False),
- ui.output_ui("value"),
+ ui.output_text("value"),
)
def server(input: Inputs, output: Outputs, session: Session):
- @render.ui
+ @render.text
def value():
return input.somevalue()
diff --git a/shiny/api-examples/input_text/app-express.py b/shiny/api-examples/input_text/app-express.py
new file mode 100644
index 000000000..8c0c30d69
--- /dev/null
+++ b/shiny/api-examples/input_text/app-express.py
@@ -0,0 +1,8 @@
+from shiny.express import input, render, ui
+
+ui.input_text("caption", "Caption:", "Data summary")
+
+
+@render.code
+def value():
+ return input.caption()
diff --git a/shiny/api-examples/input_text_area/app-express.py b/shiny/api-examples/input_text_area/app-express.py
new file mode 100644
index 000000000..4841f56ee
--- /dev/null
+++ b/shiny/api-examples/input_text_area/app-express.py
@@ -0,0 +1,25 @@
+from shiny.express import input, render, ui
+
+ui.input_text_area(
+ "caption_regular",
+ "Caption:",
+ "Data summary\nwith\nmultiple\nlines",
+)
+
+
+@render.text
+def value_regular():
+ return input.caption_regular()
+
+
+ui.input_text_area(
+ "caption_autoresize",
+ ui.markdown("Caption (w/ `autoresize=True`):"),
+ "Data summary\nwith\nmultiple\nlines",
+ autoresize=True,
+)
+
+
+@render.text
+def value_autoresize():
+ return input.caption_autoresize()
diff --git a/shiny/api-examples/insert_accordion_panel/app-express.py b/shiny/api-examples/insert_accordion_panel/app-express.py
new file mode 100644
index 000000000..fcad947f0
--- /dev/null
+++ b/shiny/api-examples/insert_accordion_panel/app-express.py
@@ -0,0 +1,26 @@
+import random
+
+from shiny import reactive
+from shiny.express import expressify, input, ui
+
+with ui.sidebar():
+ ui.input_action_button("add_panel", "Add random panel", class_="mt-3 mb-3")
+
+with ui.accordion(id="acc", multiple=True):
+ for letter in "ABCDE":
+ with ui.accordion_panel(f"Section {letter}"):
+ f"Some narrative for section {letter} "
+ "more narrative"
+
+
+@reactive.effect
+@reactive.event(input.add_panel)
+@expressify
+def _():
+ letter = str(random.randint(0, 10000))
+ with ui.hold() as panel:
+ with ui.accordion_panel(f"Section {letter}"):
+ f"Some narrative for section {letter} "
+ "more narrative"
+
+ ui.insert_accordion_panel("acc", panel[0])
diff --git a/shiny/api-examples/layout_column_wrap/app-express.py b/shiny/api-examples/layout_column_wrap/app-express.py
new file mode 100644
index 000000000..0754d8b74
--- /dev/null
+++ b/shiny/api-examples/layout_column_wrap/app-express.py
@@ -0,0 +1,19 @@
+from shiny.express import ui
+
+with ui.hold() as a_card:
+ with ui.card():
+ "A simple card"
+
+# Always has 2 columns (on non-mobile)
+with ui.layout_column_wrap(width=1 / 2):
+ a_card
+ a_card
+ a_card
+
+ui.hr()
+
+# Has three columns when viewport is wider than 750px
+with ui.layout_column_wrap(width="250px"):
+ a_card
+ a_card
+ a_card
diff --git a/shiny/api-examples/layout_columns/app-express.py b/shiny/api-examples/layout_columns/app-express.py
new file mode 100644
index 000000000..768056d5c
--- /dev/null
+++ b/shiny/api-examples/layout_columns/app-express.py
@@ -0,0 +1,38 @@
+from model_plots import (
+ plot_accuracy_over_time,
+ plot_feature_importance,
+ plot_loss_over_time,
+)
+
+from shiny.express import render, ui
+
+ui.page_opts(title="Model Dashboard")
+
+ui.markdown("Using `ui.layout_columns()` for the layout.")
+
+
+with ui.layout_columns(
+ col_widths={"sm": (5, 7, 12)},
+ # row_heights=(2, 3),
+ # height="700px",
+):
+ with ui.card(full_screen=True):
+ ui.card_header("Loss Over Time")
+
+ @render.plot
+ def loss_over_time():
+ return plot_loss_over_time()
+
+ with ui.card(full_screen=True):
+ ui.card_header("Accuracy Over Time")
+
+ @render.plot
+ def accuracy_over_time():
+ return plot_accuracy_over_time()
+
+ with ui.card(full_screen=True):
+ ui.card_header("Feature Importance")
+
+ @render.plot
+ def feature_importance():
+ return plot_feature_importance()
diff --git a/shiny/api-examples/layout_sidebar/app-express.py b/shiny/api-examples/layout_sidebar/app-express.py
new file mode 100644
index 000000000..10482a396
--- /dev/null
+++ b/shiny/api-examples/layout_sidebar/app-express.py
@@ -0,0 +1,17 @@
+import matplotlib.pyplot as plt
+import numpy as np
+
+from shiny.express import input, render, ui
+
+with ui.layout_sidebar():
+ with ui.sidebar():
+ ui.input_slider("n", "N", min=0, max=100, value=20)
+
+ @render.plot(alt="A histogram")
+ def plot() -> object:
+ np.random.seed(19680801)
+ x = 100 + 15 * np.random.randn(437)
+
+ fig, ax = plt.subplots()
+ ax.hist(x, input.n(), density=True)
+ return fig
diff --git a/shiny/api-examples/markdown/app-express.py b/shiny/api-examples/markdown/app-express.py
new file mode 100644
index 000000000..f1db29501
--- /dev/null
+++ b/shiny/api-examples/markdown/app-express.py
@@ -0,0 +1,13 @@
+from shiny.express import ui
+
+ui.markdown(
+ """
+ # Hello World
+
+ This is **markdown** and here is some `code`:
+
+ ```python
+ print('Hello world!')
+ ```
+ """
+)
diff --git a/shiny/api-examples/nav_panel/app-express.py b/shiny/api-examples/nav_panel/app-express.py
new file mode 100644
index 000000000..7342ff279
--- /dev/null
+++ b/shiny/api-examples/nav_panel/app-express.py
@@ -0,0 +1,10 @@
+from shiny.express import ui
+
+ui.page_opts(title="Basic Nav Examples")
+
+
+with ui.navset_tab():
+ with ui.nav_panel("One"):
+ "First tab content"
+ with ui.nav_panel("Two"):
+ "Second tab content"
diff --git a/shiny/api-examples/navset_hidden/app-express.py b/shiny/api-examples/navset_hidden/app-express.py
new file mode 100644
index 000000000..5fc22bd2a
--- /dev/null
+++ b/shiny/api-examples/navset_hidden/app-express.py
@@ -0,0 +1,22 @@
+from shiny import reactive
+from shiny.express import input, ui
+
+with ui.sidebar():
+ ui.input_radio_buttons("controller", "Controller", ["1", "2", "3"], selected="1")
+
+
+with ui.navset_hidden(id="hidden_tabs"):
+ with ui.nav_panel(None, value="panel1"):
+ "Panel 1 content"
+ with ui.nav_panel(None, value="panel2"):
+ "Panel 2 content"
+ with ui.nav_panel(None, value="panel3"):
+ "Panel 3 content"
+ with ui.nav_panel(None, value="panel4"):
+ "Panel 4 content"
+
+
+@reactive.Effect
+@reactive.event(input.controller)
+def update_navs():
+ ui.update_navs("hidden_tabs", selected="panel" + str(input.controller()))
diff --git a/shiny/api-examples/page_sidebar/app-express.py b/shiny/api-examples/page_sidebar/app-express.py
new file mode 100644
index 000000000..4781f851c
--- /dev/null
+++ b/shiny/api-examples/page_sidebar/app-express.py
@@ -0,0 +1,17 @@
+import matplotlib.pyplot as plt
+import numpy as np
+
+from shiny.express import input, render, ui
+
+with ui.sidebar():
+ ui.input_slider("n", "N", min=0, max=100, value=20)
+
+
+@render.plot(alt="A histogram")
+def plot() -> object:
+ np.random.seed(19680801)
+ x = 100 + 15 * np.random.randn(437)
+
+ fig, ax = plt.subplots()
+ ax.hist(x, input.n(), density=True)
+ return fig
diff --git a/shiny/api-examples/page_sidebar/app.py b/shiny/api-examples/page_sidebar/app.py
index ba84c3fe8..8ce58f8b8 100644
--- a/shiny/api-examples/page_sidebar/app.py
+++ b/shiny/api-examples/page_sidebar/app.py
@@ -14,7 +14,6 @@
def server(input: Inputs, output: Outputs, session: Session):
- @output
@render.plot(alt="A histogram")
def plot() -> object:
np.random.seed(19680801)
diff --git a/shiny/api-examples/panel_absolute/app-express.py b/shiny/api-examples/panel_absolute/app-express.py
new file mode 100644
index 000000000..8cf254ecb
--- /dev/null
+++ b/shiny/api-examples/panel_absolute/app-express.py
@@ -0,0 +1,8 @@
+from shiny.express import ui
+
+ui.h2("A basic absolute panel example")
+
+with ui.panel_absolute(draggable=True, width="300px", right="50px", top="25%"):
+ with ui.panel_well():
+ "Drag me around!"
+ ui.input_slider("n", "N", min=0, max=100, value=20)
diff --git a/shiny/api-examples/panel_absolute/app.py b/shiny/api-examples/panel_absolute/app.py
index 10fab125e..3340e5f93 100644
--- a/shiny/api-examples/panel_absolute/app.py
+++ b/shiny/api-examples/panel_absolute/app.py
@@ -9,7 +9,7 @@
draggable=True,
width="300px",
right="50px",
- top="50%",
+ top="25%",
),
)
diff --git a/shiny/api-examples/panel_conditional/app-express.py b/shiny/api-examples/panel_conditional/app-express.py
new file mode 100644
index 000000000..8f5fbb229
--- /dev/null
+++ b/shiny/api-examples/panel_conditional/app-express.py
@@ -0,0 +1,12 @@
+from shiny.express import ui
+
+ui.input_checkbox("show", "Show radio buttons", False)
+
+with ui.panel_conditional("input.show"):
+ ui.input_radio_buttons("radio", "Choose ", ["slider", "select"])
+
+with ui.panel_conditional("input.show && input.radio === 'slider'"):
+ ui.input_slider("slider", None, min=0, max=100, value=50)
+
+with ui.panel_conditional("input.show && input.radio === 'select'"):
+ ui.input_select("slider", None, ["A", "B", "C"])
diff --git a/shiny/api-examples/showcase_bottom/app-express.py b/shiny/api-examples/showcase_bottom/app-express.py
new file mode 100644
index 000000000..9b2e644bc
--- /dev/null
+++ b/shiny/api-examples/showcase_bottom/app-express.py
@@ -0,0 +1,28 @@
+from icons import piggy_bank
+
+from shiny.express import ui
+
+with ui.layout_columns():
+ with ui.value_box(
+ showcase=piggy_bank, theme="bg-gradient-orange-cyan", full_screen=True
+ ):
+ "KPI Title"
+ "$1 Billion Dollars"
+ "Up 30% VS PREVIOUS 30 DAYS"
+
+ with ui.value_box(
+ showcase=piggy_bank,
+ theme="text-green",
+ showcase_layout="top right",
+ full_screen=True,
+ ):
+ "KPI Title"
+ "$1 Billion Dollars"
+ "Up 30% VS PREVIOUS 30 DAYS"
+
+ with ui.value_box(
+ showcase=piggy_bank, theme="purple", showcase_layout="bottom", full_screen=True
+ ):
+ "KPI Title"
+ "$1 Billion Dollars"
+ "Up 30% VS PREVIOUS 30 DAYS"
diff --git a/shiny/api-examples/showcase_left_center/app-express.py b/shiny/api-examples/showcase_left_center/app-express.py
new file mode 100644
index 000000000..9b2e644bc
--- /dev/null
+++ b/shiny/api-examples/showcase_left_center/app-express.py
@@ -0,0 +1,28 @@
+from icons import piggy_bank
+
+from shiny.express import ui
+
+with ui.layout_columns():
+ with ui.value_box(
+ showcase=piggy_bank, theme="bg-gradient-orange-cyan", full_screen=True
+ ):
+ "KPI Title"
+ "$1 Billion Dollars"
+ "Up 30% VS PREVIOUS 30 DAYS"
+
+ with ui.value_box(
+ showcase=piggy_bank,
+ theme="text-green",
+ showcase_layout="top right",
+ full_screen=True,
+ ):
+ "KPI Title"
+ "$1 Billion Dollars"
+ "Up 30% VS PREVIOUS 30 DAYS"
+
+ with ui.value_box(
+ showcase=piggy_bank, theme="purple", showcase_layout="bottom", full_screen=True
+ ):
+ "KPI Title"
+ "$1 Billion Dollars"
+ "Up 30% VS PREVIOUS 30 DAYS"
diff --git a/shiny/api-examples/showcase_top_right/app-express.py b/shiny/api-examples/showcase_top_right/app-express.py
new file mode 100644
index 000000000..9b2e644bc
--- /dev/null
+++ b/shiny/api-examples/showcase_top_right/app-express.py
@@ -0,0 +1,28 @@
+from icons import piggy_bank
+
+from shiny.express import ui
+
+with ui.layout_columns():
+ with ui.value_box(
+ showcase=piggy_bank, theme="bg-gradient-orange-cyan", full_screen=True
+ ):
+ "KPI Title"
+ "$1 Billion Dollars"
+ "Up 30% VS PREVIOUS 30 DAYS"
+
+ with ui.value_box(
+ showcase=piggy_bank,
+ theme="text-green",
+ showcase_layout="top right",
+ full_screen=True,
+ ):
+ "KPI Title"
+ "$1 Billion Dollars"
+ "Up 30% VS PREVIOUS 30 DAYS"
+
+ with ui.value_box(
+ showcase=piggy_bank, theme="purple", showcase_layout="bottom", full_screen=True
+ ):
+ "KPI Title"
+ "$1 Billion Dollars"
+ "Up 30% VS PREVIOUS 30 DAYS"
diff --git a/shiny/api-examples/sidebar/app-express.py b/shiny/api-examples/sidebar/app-express.py
new file mode 100644
index 000000000..17e80bb47
--- /dev/null
+++ b/shiny/api-examples/sidebar/app-express.py
@@ -0,0 +1,42 @@
+from shiny.express import input, render, ui
+
+ui.page_opts(fillable=True)
+
+with ui.card():
+ with ui.layout_sidebar():
+ with ui.sidebar(id="sidebar_left", open="desktop"):
+ "Left sidebar content"
+
+ @render.text
+ def state_left():
+ return f"input.sidebar_left(): {input.sidebar_left()}"
+
+
+with ui.card():
+ with ui.layout_sidebar():
+ with ui.sidebar(id="sidebar_right", position="right", open="desktop"):
+ "Right sidebar content"
+
+ @render.text
+ def state_right():
+ return f"input.sidebar_right(): {input.sidebar_right()}"
+
+
+with ui.card():
+ with ui.layout_sidebar():
+ with ui.sidebar(id="sidebar_closed", open="closed"):
+ "Closed sidebar content"
+
+ @render.text
+ def state_closed():
+ return f"input.sidebar_closed(): {input.sidebar_closed()}"
+
+
+with ui.card():
+ with ui.layout_sidebar():
+ with ui.sidebar(id="sidebar_always", open="always"):
+ "Always sidebar content"
+
+ @render.text
+ def state_always():
+ return f"input.sidebar_always(): {input.sidebar_always()}"
diff --git a/shiny/api-examples/update_accordion/app-express.py b/shiny/api-examples/update_accordion/app-express.py
new file mode 100644
index 000000000..17ce91787
--- /dev/null
+++ b/shiny/api-examples/update_accordion/app-express.py
@@ -0,0 +1,16 @@
+from shiny import reactive
+from shiny.express import input, ui
+
+with ui.card():
+ ui.input_action_button("set_acc", "Only open sections A,C,E", class_="mt-3 mb-3")
+ # Provide an id to create a shiny input binding
+ with ui.accordion(id="acc", open=["Section B", "Section D"], multiple=True):
+ for letter in "ABCDE":
+ with ui.accordion_panel(f"Section {letter}"):
+ f"Some narrative for section {letter}"
+
+
+@reactive.Effect
+@reactive.event(input.set_acc)
+def open_panels():
+ ui.update_accordion("acc", show=["Section A", "Section C", "Section E"])
diff --git a/shiny/api-examples/update_accordion_panel/app-express.py b/shiny/api-examples/update_accordion_panel/app-express.py
new file mode 100644
index 000000000..15a2d47c5
--- /dev/null
+++ b/shiny/api-examples/update_accordion_panel/app-express.py
@@ -0,0 +1,31 @@
+from shiny import reactive
+from shiny.express import input, ui
+
+with ui.card():
+ ui.input_action_button(
+ "update_panel", "Only open sections A,C,E", class_="mt-3 mb-3"
+ )
+ # Provide an id to create a shiny input binding
+ with ui.accordion(id="acc", open=["Section B", "Section D"], multiple=True):
+ for letter in "ABCDE":
+ with ui.accordion_panel(f"Section {letter}", value=f"sec_{letter}"):
+ f"Some narrative for section {letter}"
+
+
+@reactive.Effect
+@reactive.event(input.update_panel)
+def _():
+ txt = " (updated)" if input.update_panel() else ""
+ show = bool(input.update_panel() % 2 == 1)
+ for letter in "ABCDE":
+ ui.update_accordion_panel(
+ "acc",
+ f"sec_{letter}",
+ f"Some{txt} narrative for section {letter}",
+ title=f"Section {letter}{txt}",
+ # Open Accordion Panel to see updated contents
+ show=show,
+ )
+ next_show_txt = "close" if show else "open"
+
+ ui.update_switch("update_panel", label=f"Update (and {next_show_txt}) Sections")
diff --git a/shiny/api-examples/update_action_button/app-express.py b/shiny/api-examples/update_action_button/app-express.py
new file mode 100644
index 000000000..375b0d258
--- /dev/null
+++ b/shiny/api-examples/update_action_button/app-express.py
@@ -0,0 +1,22 @@
+from shiny import reactive, req
+from shiny.express import input, ui
+
+with ui.sidebar():
+ ui.input_action_button("update", "Update other buttons and link")
+ ui.input_action_button("goButton", "Go")
+ ui.input_action_button("goButton2", "Go 2", icon="🤩")
+ ui.input_action_button("goButton3", "Go 3")
+ ui.input_action_link("goLink", "Go Link")
+
+
+@reactive.Effect
+def update_buttons():
+ req(input.update())
+ # Updates goButton's label and icon
+ ui.update_action_button("goButton", label="New label", icon="📅")
+ # Leaves goButton2's label unchanged and removes its icon
+ ui.update_action_button("goButton2", icon=[])
+ # Leaves goButton3's icon, if it exists, unchanged and changes its label
+ ui.update_action_button("goButton3", label="New label 3")
+ # Updates goLink's label and icon
+ ui.update_action_link("goLink", label="New link label", icon="🔗")
diff --git a/shiny/api-examples/update_action_button/app.py b/shiny/api-examples/update_action_button/app.py
index 0b08cc34a..c6d55da8c 100644
--- a/shiny/api-examples/update_action_button/app.py
+++ b/shiny/api-examples/update_action_button/app.py
@@ -1,15 +1,13 @@
from shiny import App, Inputs, Outputs, Session, reactive, req, ui
-app_ui = ui.page_fluid(
- ui.input_action_button("update", "Update other buttons and link"),
- ui.br(),
- ui.input_action_button("goButton", "Go"),
- ui.br(),
- ui.input_action_button("goButton2", "Go 2", icon="🤩"),
- ui.br(),
- ui.input_action_button("goButton3", "Go 3"),
- ui.br(),
- ui.input_action_link("goLink", "Go Link"),
+app_ui = ui.page_sidebar(
+ ui.sidebar(
+ ui.input_action_button("update", "Update other buttons and link"),
+ ui.input_action_button("goButton", "Go"),
+ ui.input_action_button("goButton2", "Go 2", icon="🤩"),
+ ui.input_action_button("goButton3", "Go 3"),
+ ui.input_action_link("goLink", "Go Link"),
+ )
)
diff --git a/shiny/api-examples/update_checkbox/app-express.py b/shiny/api-examples/update_checkbox/app-express.py
new file mode 100644
index 000000000..95a6b69fe
--- /dev/null
+++ b/shiny/api-examples/update_checkbox/app-express.py
@@ -0,0 +1,13 @@
+from shiny import reactive
+from shiny.express import input, ui
+
+"Checkbox will be checked when slider is an odd number."
+ui.input_slider("controller", "Controller", min=0, max=10, value=0, step=1)
+ui.input_checkbox("inCheckbox", "Input checkbox")
+
+
+@reactive.Effect
+def _():
+ # True if controller is odd, False if even.
+ x_even = input.controller() % 2 == 1
+ ui.update_checkbox("inCheckbox", value=x_even)
diff --git a/shiny/api-examples/update_checkbox/app.py b/shiny/api-examples/update_checkbox/app.py
index 036a4034f..5b7af883a 100644
--- a/shiny/api-examples/update_checkbox/app.py
+++ b/shiny/api-examples/update_checkbox/app.py
@@ -1,7 +1,8 @@
from shiny import App, Inputs, Outputs, Session, reactive, ui
app_ui = ui.page_fluid(
- ui.input_slider("controller", "Controller", min=0, max=1, value=0, step=1),
+ ui.p("Checkbox will be checked when slider is an odd number."),
+ ui.input_slider("controller", "Controller", min=0, max=10, value=0, step=1),
ui.input_checkbox("inCheckbox", "Input checkbox"),
)
diff --git a/shiny/api-examples/update_checkbox_group/app-express.py b/shiny/api-examples/update_checkbox_group/app-express.py
new file mode 100644
index 000000000..f2337ece5
--- /dev/null
+++ b/shiny/api-examples/update_checkbox_group/app-express.py
@@ -0,0 +1,23 @@
+from shiny import reactive
+from shiny.express import input, ui
+
+"The first checkbox group controls the second"
+ui.input_checkbox_group(
+ "inCheckboxGroup", "Input checkbox", ["Item A", "Item B", "Item C"]
+)
+ui.input_checkbox_group(
+ "inCheckboxGroup2", "Input checkbox 2", ["Item A", "Item B", "Item C"]
+)
+
+
+@reactive.Effect
+def _():
+ x = input.inCheckboxGroup()
+
+ # Can also set the label and select items
+ ui.update_checkbox_group(
+ "inCheckboxGroup2",
+ label="Checkboxgroup label " + str(len(x)),
+ choices=x,
+ selected=x,
+ )
diff --git a/shiny/api-examples/update_date/app-express.py b/shiny/api-examples/update_date/app-express.py
new file mode 100644
index 000000000..88e599303
--- /dev/null
+++ b/shiny/api-examples/update_date/app-express.py
@@ -0,0 +1,19 @@
+from datetime import date, timedelta
+
+from shiny import reactive, ui
+from shiny.express import input
+
+ui.input_slider("n", "Day of month", min=1, max=30, value=10)
+ui.input_date("inDate", "Input date")
+
+
+@reactive.Effect
+def _():
+ d = date(2013, 4, input.n())
+ ui.update_date(
+ "inDate",
+ label="Date label " + str(input.n()),
+ value=d,
+ min=d - timedelta(days=3),
+ max=d + timedelta(days=3),
+ )
diff --git a/shiny/api-examples/update_date_range/app-express.py b/shiny/api-examples/update_date_range/app-express.py
new file mode 100644
index 000000000..41defda91
--- /dev/null
+++ b/shiny/api-examples/update_date_range/app-express.py
@@ -0,0 +1,20 @@
+from datetime import date, timedelta
+
+from shiny import reactive, ui
+from shiny.express import input
+
+ui.input_slider("n", "Day of month", min=1, max=30, value=10)
+ui.input_date_range("inDateRange", "Input date")
+
+
+@reactive.Effect
+def _():
+ d = date(2013, 4, input.n())
+ ui.update_date_range(
+ "inDateRange",
+ label="Date range label " + str(input.n()),
+ start=d - timedelta(days=1),
+ end=d + timedelta(days=1),
+ min=d - timedelta(days=5),
+ max=d + timedelta(days=5),
+ )
diff --git a/shiny/api-examples/update_navs/app-express.py b/shiny/api-examples/update_navs/app-express.py
new file mode 100644
index 000000000..376fa400d
--- /dev/null
+++ b/shiny/api-examples/update_navs/app-express.py
@@ -0,0 +1,18 @@
+from shiny import reactive
+from shiny.express import input, ui
+
+with ui.sidebar():
+ ui.input_slider("controller", "Controller", min=1, max=3, value=1)
+
+with ui.navset_tab(id="inTabset"):
+ with ui.nav_panel("Panel 1", value="panel1"):
+ "Panel 1 content"
+ with ui.nav_panel("Panel 2", value="panel2"):
+ "Panel 2 content"
+ with ui.nav_panel("Panel 3", value="panel3"):
+ "Panel 3 content"
+
+
+@reactive.Effect
+def _():
+ ui.update_navs("inTabset", selected="panel" + str(input.controller()))
diff --git a/shiny/api-examples/update_navs/app.py b/shiny/api-examples/update_navs/app.py
index 6a8e392a9..cec4df882 100644
--- a/shiny/api-examples/update_navs/app.py
+++ b/shiny/api-examples/update_navs/app.py
@@ -1,19 +1,13 @@
from shiny import App, Inputs, Outputs, Session, reactive, ui
-app_ui = ui.page_fixed(
- ui.layout_sidebar(
- ui.panel_sidebar(
- ui.input_slider("controller", "Controller", min=1, max=3, value=1)
- ),
- ui.panel_main(
- ui.navset_card_tab(
- ui.nav_panel("Panel 1", "Panel 1 content", value="panel1"),
- ui.nav_panel("Panel 2", "Panel 2 content", value="panel2"),
- ui.nav_panel("Panel 3", "Panel 3 content", value="panel3"),
- id="inTabset",
- ),
- ),
- )
+app_ui = ui.page_navbar(
+ ui.nav_panel("Panel 1", "Panel 1 content", value="panel1"),
+ ui.nav_panel("Panel 2", "Panel 2 content", value="panel2"),
+ ui.nav_panel("Panel 3", "Panel 3 content", value="panel3"),
+ sidebar=ui.sidebar(
+ ui.input_slider("controller", "Controller", min=1, max=3, value=1)
+ ),
+ id="inTabset",
)
diff --git a/shiny/api-examples/update_numeric/app-express.py b/shiny/api-examples/update_numeric/app-express.py
new file mode 100644
index 000000000..3f3c5a97b
--- /dev/null
+++ b/shiny/api-examples/update_numeric/app-express.py
@@ -0,0 +1,20 @@
+from shiny import reactive, ui
+from shiny.express import input
+
+ui.input_slider("controller", "Controller", min=0, max=20, value=10)
+ui.input_numeric("inNumber", "Input number", 0)
+ui.input_numeric("inNumber2", "Input number 2", 0)
+
+
+@reactive.Effect
+def _():
+ x = input.controller()
+ ui.update_numeric("inNumber", value=x)
+ ui.update_numeric(
+ "inNumber2",
+ label="Number label " + str(x),
+ value=x,
+ min=x - 10,
+ max=x + 10,
+ step=5,
+ )
diff --git a/shiny/api-examples/update_popover/app-express.py b/shiny/api-examples/update_popover/app-express.py
new file mode 100644
index 000000000..6650216b7
--- /dev/null
+++ b/shiny/api-examples/update_popover/app-express.py
@@ -0,0 +1,29 @@
+from shiny import reactive, req
+from shiny.express import input, ui
+
+with ui.sidebar():
+ ui.input_action_button("btn_show", "Show popover", class_="mt-3 me-3")
+ ui.input_action_button("btn_close", "Close popover", class_="mt-3 me-3")
+ with ui.popover(id="popover_id"):
+ ui.input_action_button("btn_w_popover", "A button w/ a popover", class_="mt-3")
+ "A message"
+
+
+@reactive.Effect
+def _():
+ req(input.btn_show())
+
+ ui.update_popover("popover_id", show=True)
+
+
+@reactive.Effect
+def _():
+ req(input.btn_close())
+
+ ui.update_popover("popover_id", show=False)
+
+
+@reactive.Effect
+def _():
+ req(input.btn_w_popover())
+ ui.notification_show("Button clicked!", duration=3, type="message")
diff --git a/shiny/api-examples/update_popover/app.py b/shiny/api-examples/update_popover/app.py
index f54f18de9..c1cb842a1 100644
--- a/shiny/api-examples/update_popover/app.py
+++ b/shiny/api-examples/update_popover/app.py
@@ -1,15 +1,17 @@
from shiny import App, Inputs, Outputs, Session, reactive, req, ui
-app_ui = ui.page_fluid(
- ui.input_action_button("btn_show", "Show popover", class_="mt-3 me-3"),
- ui.input_action_button("btn_close", "Close popover", class_="mt-3 me-3"),
- ui.br(),
- ui.br(),
- ui.popover(
- ui.input_action_button("btn_w_popover", "A button w/ a popover", class_="mt-3"),
- "A message",
- id="popover_id",
- ),
+app_ui = ui.page_sidebar(
+ ui.sidebar(
+ ui.input_action_button("btn_show", "Show popover", class_="mt-3 me-3"),
+ ui.input_action_button("btn_close", "Close popover", class_="mt-3 me-3"),
+ ui.popover(
+ ui.input_action_button(
+ "btn_w_popover", "A button w/ a popover", class_="mt-3"
+ ),
+ "A message",
+ id="popover_id",
+ ),
+ )
)
diff --git a/shiny/api-examples/update_radio_buttons/app-express.py b/shiny/api-examples/update_radio_buttons/app-express.py
new file mode 100644
index 000000000..b1f601e0b
--- /dev/null
+++ b/shiny/api-examples/update_radio_buttons/app-express.py
@@ -0,0 +1,23 @@
+from shiny import reactive, ui
+from shiny.express import input
+
+"The first radio button group controls the second"
+ui.input_radio_buttons(
+ "inRadioButtons", "Input radio buttons", ["Item A", "Item B", "Item C"]
+)
+ui.input_radio_buttons(
+ "inRadioButtons2", "Input radio buttons 2", ["Item A", "Item B", "Item C"]
+)
+
+
+@reactive.Effect
+def _():
+ x = input.inRadioButtons()
+
+ # Can also set the label and select items
+ ui.update_radio_buttons(
+ "inRadioButtons2",
+ label="Radio buttons label " + x,
+ choices=[x],
+ selected=x,
+ )
diff --git a/shiny/api-examples/update_select/app-express.py b/shiny/api-examples/update_select/app-express.py
new file mode 100644
index 000000000..15c087989
--- /dev/null
+++ b/shiny/api-examples/update_select/app-express.py
@@ -0,0 +1,26 @@
+from shiny import reactive
+from shiny.express import input, ui
+
+ui.tags.p("The checkbox group controls the select input")
+ui.input_checkbox_group(
+ "inCheckboxGroup", "Input checkbox", ["Item A", "Item B", "Item C"]
+)
+ui.input_select("inSelect", "Select input", ["Item A", "Item B", "Item C"])
+
+
+@reactive.Effect
+def _():
+ x = input.inCheckboxGroup()
+
+ # Can use [] to remove all choices
+ if x is None:
+ x = []
+ elif isinstance(x, str):
+ x = [x]
+
+ ui.update_select(
+ "inSelect",
+ label="Select input label " + str(len(x)),
+ choices=x,
+ selected=x[len(x) - 1] if len(x) > 0 else None,
+ )
diff --git a/shiny/api-examples/update_selectize/app-express.py b/shiny/api-examples/update_selectize/app-express.py
new file mode 100644
index 000000000..d2a67c8c9
--- /dev/null
+++ b/shiny/api-examples/update_selectize/app-express.py
@@ -0,0 +1,14 @@
+from shiny import reactive
+from shiny.express import ui
+
+ui.input_selectize("x", "Server side selectize", choices=[], multiple=True)
+
+
+@reactive.Effect
+def _():
+ ui.update_selectize(
+ "x",
+ choices=[f"Foo {i}" for i in range(10000)],
+ selected=["Foo 0", "Foo 1"],
+ server=True,
+ )
diff --git a/shiny/api-examples/update_sidebar/app-express.py b/shiny/api-examples/update_sidebar/app-express.py
new file mode 100644
index 000000000..3176c0244
--- /dev/null
+++ b/shiny/api-examples/update_sidebar/app-express.py
@@ -0,0 +1,27 @@
+from shiny import reactive
+from shiny.express import input, render, ui
+
+with ui.sidebar(id="sidebar"):
+ "Sidebar content"
+ ui.input_text("foo", "Foo")
+
+with ui.layout_columns():
+ ui.input_action_button("open_sidebar", label="Open sidebar", class_="me-3")
+ ui.input_action_button("close_sidebar", label="Close sidebar", class_="me-3")
+
+
+@render.text
+def state():
+ return f"input.sidebar(): {input.sidebar()}"
+
+
+@reactive.Effect
+@reactive.event(input.open_sidebar)
+def _():
+ ui.update_sidebar("sidebar", show=True)
+
+
+@reactive.Effect
+@reactive.event(input.close_sidebar)
+def _():
+ ui.update_sidebar("sidebar", show=False)
diff --git a/shiny/api-examples/update_sidebar/app.py b/shiny/api-examples/update_sidebar/app.py
index 4c27ae57a..4fc48efb3 100644
--- a/shiny/api-examples/update_sidebar/app.py
+++ b/shiny/api-examples/update_sidebar/app.py
@@ -2,10 +2,10 @@
app_ui = ui.page_sidebar(
ui.sidebar("Sidebar content", id="sidebar"),
- ui.input_action_button("open_sidebar", label="Open sidebar", class_="me-3"),
- ui.input_action_button("close_sidebar", label="Close sidebar", class_="me-3"),
- ui.br(),
- ui.br(),
+ ui.layout_columns(
+ ui.input_action_button("open_sidebar", label="Open sidebar", class_="me-3"),
+ ui.input_action_button("close_sidebar", label="Close sidebar", class_="me-3"),
+ ),
ui.output_text_verbatim("state"),
fillable=False,
)
diff --git a/shiny/api-examples/update_slider/app-express.py b/shiny/api-examples/update_slider/app-express.py
new file mode 100644
index 000000000..049a888d8
--- /dev/null
+++ b/shiny/api-examples/update_slider/app-express.py
@@ -0,0 +1,17 @@
+from shiny import reactive
+from shiny.express import input, ui
+
+with ui.sidebar():
+ ui.tags.p("The first slider controls the second")
+ ui.input_slider("control", "Controller:", min=0, max=20, value=10, step=1)
+ ui.input_slider("receive", "Receiver:", min=0, max=20, value=10, step=1)
+
+
+@reactive.Effect
+def _():
+ val = input.control()
+ # Control the value, min, max, and step.
+ # Step size is 2 when input value is even; 1 when value is odd.
+ ui.update_slider(
+ "receive", value=val, min=int(val / 2), max=val + 4, step=(val + 1) % 2 + 1
+ )
diff --git a/shiny/api-examples/update_slider/app.py b/shiny/api-examples/update_slider/app.py
index 923d12dcc..5826f4293 100644
--- a/shiny/api-examples/update_slider/app.py
+++ b/shiny/api-examples/update_slider/app.py
@@ -1,13 +1,10 @@
from shiny import App, Inputs, Outputs, Session, reactive, ui
-app_ui = ui.page_fixed(
- ui.layout_sidebar(
- ui.panel_sidebar(
- ui.tags.p("The first slider controls the second"),
- ui.input_slider("control", "Controller:", min=0, max=20, value=10, step=1),
- ui.input_slider("receive", "Receiver:", min=0, max=20, value=10, step=1),
- ),
- ui.panel_main("Main app content"),
+app_ui = ui.page_sidebar(
+ ui.sidebar(
+ ui.tags.p("The first slider controls the second"),
+ ui.input_slider("control", "Controller:", min=0, max=20, value=10, step=1),
+ ui.input_slider("receive", "Receiver:", min=0, max=20, value=10, step=1),
)
)
diff --git a/shiny/api-examples/update_text/app-express.py b/shiny/api-examples/update_text/app-express.py
new file mode 100644
index 000000000..dbd329e73
--- /dev/null
+++ b/shiny/api-examples/update_text/app-express.py
@@ -0,0 +1,15 @@
+from shiny import reactive
+from shiny.express import input, ui
+
+ui.input_slider("controller", "Controller", min=0, max=20, value=10)
+ui.input_text("inText", "Input text")
+ui.input_text("inText2", "Input text 2")
+
+
+@reactive.Effect
+def _():
+ x = str(input.controller())
+ # This will change the value of input$inText, based on x
+ ui.update_text("inText", value="New text " + x)
+ # Can also set the label, this time for input$inText2
+ ui.update_text("inText2", label="New label " + x, value="New text" + x)
diff --git a/shiny/api-examples/update_tooltip/app-express.py b/shiny/api-examples/update_tooltip/app-express.py
new file mode 100644
index 000000000..d2bf8ea44
--- /dev/null
+++ b/shiny/api-examples/update_tooltip/app-express.py
@@ -0,0 +1,40 @@
+from shiny import reactive, req
+from shiny.express import input, ui
+
+with ui.sidebar():
+ ui.input_action_button("btn_show", "Show tooltip", class_="mt-3 me-3")
+ ui.input_action_button("btn_close", "Close tooltip", class_="mt-3 me-3")
+ ui.input_action_button(
+ "btn_update", "Update tooltip phrase (and show tooltip)", class_="mt-3 me-3"
+ )
+ with ui.tooltip(id="tooltip_id"):
+ ui.input_action_button("btn_w_tooltip", "A button w/ a tooltip", class_="mt-3")
+ "A message"
+
+
+@reactive.Effect
+def _():
+ req(input.btn_show())
+
+ ui.update_tooltip("tooltip_id", show=True)
+
+
+@reactive.Effect
+def _():
+ req(input.btn_close())
+
+ ui.update_tooltip("tooltip_id", show=False)
+
+
+@reactive.Effect
+@reactive.event(input.btn_update)
+def _():
+ content = "A " + " ".join(["NEW" for _ in range(input.btn_update())]) + " message"
+
+ ui.update_tooltip("tooltip_id", content, show=True)
+
+
+@reactive.Effect
+def _():
+ req(input.btn_w_tooltip())
+ ui.notification_show("Button clicked!", duration=3, type="message")
diff --git a/shiny/api-examples/update_tooltip/app.py b/shiny/api-examples/update_tooltip/app.py
index aa81eee94..c3e04e3c2 100644
--- a/shiny/api-examples/update_tooltip/app.py
+++ b/shiny/api-examples/update_tooltip/app.py
@@ -1,19 +1,20 @@
from shiny import App, Inputs, Outputs, Session, reactive, req, ui
-app_ui = ui.page_fluid(
- ui.input_action_button("btn_show", "Show tooltip", class_="mt-3 me-3"),
- ui.input_action_button("btn_close", "Close tooltip", class_="mt-3 me-3"),
- ui.br(),
- ui.input_action_button(
- "btn_update", "Update tooltip phrase (and show tooltip)", class_="mt-3 me-3"
- ),
- ui.br(),
- ui.br(),
- ui.tooltip(
- ui.input_action_button("btn_w_tooltip", "A button w/ a tooltip", class_="mt-3"),
- "A message",
- id="tooltip_id",
- ),
+app_ui = ui.page_sidebar(
+ ui.sidebar(
+ ui.input_action_button("btn_show", "Show tooltip", class_="mt-3 me-3"),
+ ui.input_action_button("btn_close", "Close tooltip", class_="mt-3 me-3"),
+ ui.input_action_button(
+ "btn_update", "Update tooltip phrase (and show tooltip)", class_="mt-3 me-3"
+ ),
+ ui.tooltip(
+ ui.input_action_button(
+ "btn_w_tooltip", "A button w/ a tooltip", class_="mt-3"
+ ),
+ "A message",
+ id="tooltip_id",
+ ),
+ )
)
diff --git a/shiny/api-examples/value_box/app-express.py b/shiny/api-examples/value_box/app-express.py
new file mode 100644
index 000000000..9b2e644bc
--- /dev/null
+++ b/shiny/api-examples/value_box/app-express.py
@@ -0,0 +1,28 @@
+from icons import piggy_bank
+
+from shiny.express import ui
+
+with ui.layout_columns():
+ with ui.value_box(
+ showcase=piggy_bank, theme="bg-gradient-orange-cyan", full_screen=True
+ ):
+ "KPI Title"
+ "$1 Billion Dollars"
+ "Up 30% VS PREVIOUS 30 DAYS"
+
+ with ui.value_box(
+ showcase=piggy_bank,
+ theme="text-green",
+ showcase_layout="top right",
+ full_screen=True,
+ ):
+ "KPI Title"
+ "$1 Billion Dollars"
+ "Up 30% VS PREVIOUS 30 DAYS"
+
+ with ui.value_box(
+ showcase=piggy_bank, theme="purple", showcase_layout="bottom", full_screen=True
+ ):
+ "KPI Title"
+ "$1 Billion Dollars"
+ "Up 30% VS PREVIOUS 30 DAYS"
diff --git a/shiny/api-examples/value_box/app.py b/shiny/api-examples/value_box/app.py
index 1d5416ba7..804e0f957 100644
--- a/shiny/api-examples/value_box/app.py
+++ b/shiny/api-examples/value_box/app.py
@@ -3,7 +3,7 @@
from shiny import App, ui
app_ui = ui.page_fluid(
- ui.layout_column_wrap(
+ ui.layout_columns(
ui.value_box(
"KPI Title",
"$1 Billion Dollars",