dreamRs / shinyWidgets

shinyWidgets : Extend widgets available in shiny
https://dreamrs.github.io/shinyWidgets/
GNU General Public License v3.0
832 stars 153 forks source link

Not able to click whole button in quarto #683

Open rjake opened 7 months ago

rjake commented 7 months ago

When I use radioGroupButtons() or checkboxGroupButtons() in quarto, the buttons do not display as expected.

I am using shinyWidgets 0.8.3 and quarto 1.4.552.

Please let me know if this issue should go in the quarto repo instead.

test.qmd

image

---
title: "Test"
format: html
---

```{r}
shinyWidgets::radioGroupButtons(
  inputId = "test-radio",
  label = NULL,
  choices = LETTERS[1:3]
)

shinyWidgets::checkboxGroupButtons(
  inputId = "test-checkbox",
  label = NULL,
  choices = LETTERS[1:3]
)
pingfan-hu commented 7 months ago

I have the same problem. It seems quarto doc is overlaying its own theme upon the radio buttons. Hopefully there is a way to set the css or scss to overlay the default quarto setting.

pvictor commented 7 months ago

radioGroupButtons() and checkboxGroupButtons() generate a different HTML markup based on the Bootstrap version used. Here it seems it generate markup for BS3 (the default) but Quarto is using BS5, so apparently the theme isn't retrieved properly by shiny::getCurrentTheme().

PS: you also need server: shiny in you yaml config

jhelvy commented 7 months ago

Tagging @cderv here - do you think this should be posted as an issue in Quarto? Or perhaps do you have a solution to use a different version of Bootstrap (if that is indeed the source of the issue)?

Here's a more complete reproducible example of the issue:

---
title: "Test"
format: html
server: shiny
---

```{r}
shinyWidgets::radioGroupButtons(
  inputId = "test_radio",
  label = NULL,
  choices = LETTERS[1:3]
)

shinyWidgets::checkboxGroupButtons(
  inputId = "test_checkbox",
  label = NULL,
  choices = LETTERS[1:3]
)

h1('Radio button selected:')
textOutput("radio")
h1('Checkbox selected:')
textOutput("checkbox")
#| context: server

output$radio <- renderText(input$test_radio)
output$checkbox <- renderText(input$test_checkbox)

Also note that the widgets render and behave as expected as an equivalent non-Quarto shiny app:

```r
library(shiny)

ui <- fluidPage(

  sidebarLayout(
    sidebarPanel( 
      shinyWidgets::radioGroupButtons(
        inputId = "test_radio",
        label = NULL,
        choices = LETTERS[1:3]
      ),
      shinyWidgets::checkboxGroupButtons(
        inputId = "test_checkbox",
        label = NULL,
        choices = LETTERS[1:3]
      )
    ),
    mainPanel(
      h1('Radio button selected:'),
      textOutput("radio"), 
      h1('Checkbox selected:'),
      textOutput("checkbox")
    )
  )
)

server <- function(input, output) {
  output$radio <- renderText(input$test_radio)
  output$checkbox <- renderText(input$test_checkbox)
}

shinyApp(ui = ui, server = server)
cderv commented 7 months ago

Here it seems it generate markup for BS3 (the default) but Quarto is using BS5

I can confirm that Quarto is using Bootstrap 5 - so shinyWidgets needs to be outputting some HTML compatible with Bootstrap 5

so apparently the theme isn't retrieved properly by shiny::getCurrentTheme().

Is shiny::getCurrentTheme() required to ShinyWidgets to work ? Because I don't think anything is set in quarto context for this. Nor for bslib::bs_current_theme().

I don't know how shiny theming works for a quarto shiny document 🤔

So I don't know where the adjustment lies. I know bslib components required some adjustment for everything to be included in Quarto documents.

So not sure it is directly linked to Quarto here. It could be involved to pass or set some information but as a reminder Quarto does not use R package bslib for the theming - it uses same adapted Bootstrap version but not the R package and all that it does.

Happy to help if I can when I understand how it should work.

jhelvy commented 7 months ago

It actually looks like someone accounted for the different Bootstrap versions here. There are markup_buttons_radio_bs3() and markup_buttons_radio_bs5() functions present. But if Quarto is using its own adapted bootstrap version, maybe an additional workaround is needed. I don't know enough to know the fix either or whether it should be in {shinyWidgets} or Quarto.

cderv commented 7 months ago

FWIW looking at shinyWidgets code base, I can see that it uses shiny::getCurrentTheme() which rely on shiny information and bslib theme version. It seems it can be tricked by setting an option.

outdated: see other answer below If I set this option for the document ````markdown ```{r} options(bootstrapTheme = "bs_version_5") ``` ```` then **shinyWidgets** will correctly load the bs5 component and not the bs3 as default. And it seems to work ![image](https://github.com/dreamRs/shinyWidgets/assets/6791940/4659cfa9-fd1f-436e-9610-bc25ccc544a4)

I don't know how it should happen and how bslib nor shiny do a make its theme component decision, but I guess shinyWidget could probably default to bs5 inside quarto content (instead of bs3)

cderv commented 7 months ago

But if Quarto is using its own adapted bootstrap version, maybe an additional workaround is needed.

Quarto is using Bootstrap 5, but it does not build on bootstrap directly but on the version of boostrap from bslib bslib does include the bootstrap source and some adaptation https://github.com/rstudio/bslib/tree/main/inst Quarto takes some components and other resources there (for the curious it is here in the source

jhelvy commented 7 months ago

If I set this option for the document

```{r}
options(bootstrapTheme = "bs_version_5")


then **shinyWidgets** will correctly load the bs5 component and not the bs3 as default. And it seems to work

I'm not able to get this to work. If I render this basic example, it still has the issue:

---
title: "Test"
format: html
---

```{r}
options(bootstrapTheme = "bs_version_5")

shinyWidgets::radioGroupButtons(
  inputId = "test_radio",
  label = NULL,
  choices = LETTERS[1:3]
)

shinyWidgets::checkboxGroupButtons(
  inputId = "test_checkbox",
  label = NULL,
  choices = LETTERS[1:3]
)


![Screen Shot 2024-04-02 at 09 12 24](https://github.com/dreamRs/shinyWidgets/assets/9012994/e6ce6d74-fb36-4c7d-8624-b5019c0e870e)
pvictor commented 7 months ago

You can use shiny::shinyOptions(bootstrapTheme = bslib::bs_theme(version = 5L)) to set theme, but note that this isn't the used by Quarto, so defining variables here wont't do anything.

Full example:

quarto doc:

---
title: "Test"
format:
  html: 
    theme:
      - default
      - custom.scss
server: shiny
---

```{r}
# not used, only to tell shinyWidgets to use proper markup
shiny::shinyOptions(bootstrapTheme = bslib::bs_theme(version = 5L, primary = "firebrick")) 
# shiny::getCurrentTheme()
shinyWidgets::radioGroupButtons(
  inputId = "test_radio",
  label = NULL,
  choices = LETTERS[1:3]
)

shinyWidgets::checkboxGroupButtons(
  inputId = "test_checkbox",
  label = NULL,
  choices = LETTERS[1:3]
)
#| context: server

custom.scss file:

/-- scss:defaults --/ $primary: purple !default;

jhelvy commented 7 months ago

Okay using shiny::shinyOptions(bootstrapTheme = bslib::bs_theme(version = 5L)) worked - the buttons rendered properly. But they look different from the default shiny buttons - is that what you meant by "this isn't the used by Quarto, so defining variables here wont't do anything."? Or is that why you were showing a custom scss theme? I suppose users can change the css to make them look however they want.

Screen Shot 2024-04-02 at 10 47 40

cderv commented 7 months ago

@jhelvy sorry I mixed up. shiny::shinyOptions is the way to set this. I have hidden my post. Not sure what I did precisely... 🤔

Regarding the theming, some SCSS variable may need to be defined to get the same exact default theme as in shiny or markdown. I believe the blue you see here comes from the primary color, as tweaked by @pvictor to get it purple.

This is controlled by the Quarto theme option: https://quarto.org/docs/output-formats/html-themes.html

Default used is bootswatch default theme.