Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conditionally show content in full screen cards #1102

Open
gadenbuie opened this issue Aug 20, 2024 · 2 comments
Open

Conditionally show content in full screen cards #1102

gadenbuie opened this issue Aug 20, 2024 · 2 comments

Comments

@gadenbuie
Copy link
Member

gadenbuie commented Aug 20, 2024

Feature request

It'd be nice to directly support conditionally shown content in full-screen cards. Here's how you can get there today.

  1. Add conditional content in a card_body() with class = "card-reveal-full-screen".

    card(
      "A fancy table",
      card_body(
        class = "card-reveal-full-screen",
        reactableOutput("table")
      ),
      full_screen = TRUE
    )

    The class can be named anything else (in case you think of a better name); what's important is that it's coupled with some custom CSS in the next step.

  2. Use custom CSS to toggle the visibility of that card body area.

    .bslib-card[data-full-screen="false"] > .card-reveal-full-screen {
      display: none;
    }

    The above CSS hides elements with .card-reveal-full-screen, conveniently hiding the table output in the example above. By using [data-full-screen="false"] we also stay out of the way of the default presentation when in full-screen mode; in this case the card_body() around the table wants to have display: flex.

Example app

Here's a full example also available on shinylive.io/r:

library(shiny)
library(bslib)
library(reactable)

ui <- page_fluid(
  card(
    "A fancy table",
    card_body(
      class = "card-reveal-full-screen",
      reactableOutput("table")
    ),
    full_screen = TRUE
  ),
  includeCSS("card-reveal-full-screen.css")
)

server <- function(input, output) {
  output$table <- renderReactable({
    reactable(mtcars)
  })
}

shinyApp(ui = ui, server = server)
/* card-reveal-full-screen.css */
.bslib-card[data-full-screen="false"] > .card-reveal-full-screen {
  display: none;
}

API brainstorm

Two options that occur to me:

  1. We could add an argument to card_body(), e.g. card_body(show_when = c("both", "expanded", "collapsed")).
  2. Or we could add a new function wrapping card_body(), e.g. card_body_full_screen().

I lean toward adding an argument to card_body() for discoverability, backwards compat, etc.

Naming is also complicated. I can see a use case for both showing and hiding content in the full screen mode, e.g. having a short summary that's replaced with longer content (note this can also be done with dynamic UI, but I think it'd be easier to reason about with an explicit argument/function). This means that a "full screen" option would have a paired "not full screen" option, which I find less compelling than "expanded" and "collapsed".

@gadenbuie
Copy link
Member Author

Also worth noting: there's a way to do this using the input${card_id}_full_screen reactive. I think there is room for both approaches, especially because the server-managed hiding is a little cumbersome. (See rstudio/htmltools#434.)

@gadenbuie
Copy link
Member Author

gadenbuie commented Aug 21, 2024

The same approach works for value boxes but requires more complicated CSS:

.bslib-value-box[data-full-screen="false"] > .card-body > .value-box-area > .card-reveal-full-screen,
.bslib-value-box[data-full-screen="false"] > .card-body > .value-box-grid > .value-box-area > .card-reveal-full-screen {
  display: none;
}

Example app:

library(shiny)
library(bslib)
library(reactable)

ui <- page_fluid(
  value_box(
    title = "mtcars",
    value = sprintf("%d cars", nrow(mtcars)),
    card_body(
      class = "card-reveal-full-screen",
      reactableOutput("table")
    ),
    showcase = bsicons::bs_icon("car-front-fill"),
    showcase_layout = showcase_left_center(width_full_screen = "100px"),
    full_screen = TRUE
  ),
  includeCSS("card-reveal-full-screen.css")
)

server <- function(input, output) {
  output$table <- renderReactable({
    reactable(mtcars)
  })
}

shinyApp(ui = ui, server = server)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant