Grey placeholder shapes shown while content is on its way, then the content
itself. In Shiny the usual pattern is to start with loading = TRUE and
switch it off from the server once the work is done.
Usage
el_skeleton(
id = NULL,
...,
loading = TRUE,
rows = NULL,
animated = NULL,
count = NULL,
throttle = NULL,
width = NULL,
class = NULL,
style = NULL,
slots = NULL,
session = NULL
)
update_el_skeleton(
session = shiny::getDefaultReactiveDomain(),
id,
loading = NULL,
rows = NULL,
animated = NULL,
count = NULL
)Arguments
- id
Component ID. Auto-generated if
NULL.- ...
The real content, shown once
loadingisFALSE. A shiny.element component here is absorbed, not nested.- loading
Whether to show the placeholder. Default
TRUE.- rows
Number of placeholder lines. Default
3.- animated
Whether the placeholder shimmers.
- count
How many copies of the placeholder to show.
- throttle
Delay in milliseconds before the placeholder appears, so a fast load does not flash it.
- width
Component width, as a CSS unit.
- class, style
Extra classes and inline style on the skeleton, as Element passes them to its root:
style = "display: flex; gap: 8px"lays several copies of the placeholder side by side.- slots
Named list of Element slot contents.
templatereplaces the placeholder's shape; build it fromel_skeleton_item().- session
In
el_skeleton(), deprecated: inside a module, wrapidinns(), as for any Shiny input; a session given here namespacesidonce more, with a warning. Inupdate_el_skeleton(), the Shiny session, the current one by default, as forshiny::updateTextInput().
Updating from the server
Server-side update for el_skeleton(). loading = FALSE swaps the
placeholder for the real content.
update_el_skeleton() is called for its side effect and returns NULL invisibly.
Examples
el_skeleton("report", rows = 4, animated = TRUE, shiny::tableOutput("summary"))
#> <div id="report" data-shiny-vue style="display: contents">
#> <script type="text/x-template" data-shiny-vue-template><div id="report_container" style="display: contents">
#> <el-skeleton :loading="skLoading" :rows="skRows === null ? undefined : skRows" :animated="skAnimated === null ? undefined : skAnimated" :count="skCount === null ? undefined : skCount" :throttle="skThrottle === null ? undefined : skThrottle">
#> <div>
#> <div id="summary" class="shiny-html-output shiny-table-output"></div>
#> </div>
#> </el-skeleton>
#> </div></script>
#> <script type="application/json" data-shiny-vue-options>{"options":{"data":{"skLoading":true,"skRows":4,"skAnimated":true,"skCount":null,"skThrottle":null}},"input":null,"rate":null,"type":null,"use":["shinyElement.plugin"],"evals":[]}</script>
#> </div>
if (interactive()) {
library(shiny)
ui <- el_page(el_skeleton("report", animated = TRUE, tableOutput("summary")))
server <- function(input, output, session) {
output$summary <- renderTable({
Sys.sleep(2)
on.exit(update_el_skeleton(session, "report", loading = FALSE))
head(mtcars)
})
}
shinyApp(ui, server)
}
if (interactive()) {
# inside a server function
observeEvent(result(), {
update_el_skeleton(session, "report", loading = FALSE)
})
}