I’m trying to create a busy indicator while generating a table using ui.busy_indicators
. However, the spinner does not appear when using ui.output_table
. If I replace ui.output_table
with ui.output_plot
or ui.output_data_frame
, the spinner works as expected. This makes me wonder if ui.busy_indicators
is incompatible with ui.output_table
.
import time
import numpy as np
import seaborn as sns
from shiny import App, render, ui
import pandas as pd
app_ui = ui.page_fluid(
#ui.output_plot("plot"),
ui.output_table("table"),
ui.busy_indicators.use(),
)
def server(input):
@render.plot
def plot():
time.sleep(3)
sns.lineplot(x=np.arange(100), y=np.random.randn(100))
@render.table
def table():
time.sleep(3)
df = pd.DataFrame(np.random.randn(10, 10), columns=[f'col_{i}' for i in range(10)])
return df
app = App(app_ui, server)
Busy indicators are currently not working combined with ui.output_table()
. For R Shiny, a similar issue was reported in rstudio/shiny#4169 and recently implemented in rstudio/shiny/pull/4172.
While this is not implemented in Shiny for Python, we can mimic what was implemented within the above PR: Add a class to the table output using Tag.add_class()
and add CSS which essentially applies display: unset;
to the relevant selector, it deactivates the otherwise used display: none;
what disables the spinner.
import time
import numpy as np
from shiny import App, render, ui
import pandas as pd
app_ui = ui.page_fluid(
ui.input_action_button("run_tbl", "Run table"),
ui.output_table("table").add_class("shiny-table-output"),
ui.busy_indicators.use(),
ui.busy_indicators.options(spinner_type="bars2"),
ui.tags.style(
"""
/* Disable display:none; which is currently set on some outputs */
[data-shiny-busy-spinners] .recalculating.shiny-html-output.shiny-table-output::after {
display: unset;
}
/* Hide the pulse if there are spinners on the page */
[data-shiny-busy-spinners][data-shiny-busy-pulse].shiny-busy:has(.recalculating.shiny-table-output)::after {
display: none;
}
"""
)
)
def server(input):
@render.table
def table():
input.run_tbl()
time.sleep(3)
df = pd.DataFrame(np.random.randn(10, 10), columns=[f'col_{i}' for i in range(10)])
return df
app = App(app_ui, server)