dreamRs / shinyWidgets

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

`pickerInput` frozen with broken CSS #568

Closed matherealize closed 1 year ago

matherealize commented 1 year ago

First off, I apologize in advance that I cannot produce a reproducible example, as I can't pinpoint the exact problem.

I'm using a pickerIinput inside an bslib::accordion (development version 0.4.2.9000). This works without issues in a small example such as the following.

Working example:

library(shiny)
library(bslib)
library(bsicons)

ui <- navbarPage(
    title = "Synthetic Symbols System",
    theme = bs_theme(bootswatch = "minty", 
                     version = 5),
    collapsible = TRUE, 
    tabPanel(
        title = "Synthesize",
        sidebarLayout(
            sidebarPanel(
                width = 3, 
                accordion(
                    accordion_panel(
                        "slider",
                        sliderInput("slider", "sliderInput()", min = 0, max = 100, value = c(30, 70), step = 20)
                    ),
                    accordion_panel(
                        "slider1", icon = bs_icon("alt"),
                        shinyWidgets::pickerInput(
                            "hello", "hello", 
                            choices = c("a", "b")
                        )
                    ),
                    id = "acc"
                )
            ),
            mainPanel(
                width = 9
            )
        )
    )
)

server <- function(input, output) {
    observe(print(input$acc))
}

shinyApp(ui, server)

The picker looks correct and works. In the resulting .html, among others, the following js are included (abbreviated).

<link href="[shinyWidgets/bootstrap-select-1.14.0-beta2/css/bootstrap-select.min.css]...
<script src="[shinyWidgets/bootstrap-select-1.14.0-beta2/js/bootstrap-select.min.js]....

In another, larger UI with the same setup (can't share this one unfortunately) I want to employ a similar pickerInput inside a (larger) accordion, but the result is a broken control element, with no functionality (nothing happens when I click on it), and seemingly wrong CSS colors.

image

In the resulting .html I find other js included as above

<link href="[shinyWidgets/bootstrap-select/css/bootstrap-select.min.css]...
<script src="[shinyWidgets/bootstrap-select/js/bootstrap-select.min.js]...

A really dirty solution to the problem actually seems to be to copy the contents of shinyWidgets/assets/bootstrap-select-1.14.0-beta2 to shinyWidgets/assets/bootstrap-select. Then it works in the bigger UI as well...

Any ideas what might be causing this, and a "real" solution to the issue would be greatly appreciated. Thank you! :)

pvictor commented 1 year ago

This is related to the way your construct your UI, what happens is that when pickerInput() is called it detect the Bootstrap theme used and load the appropriate dependency, here it seems that the theme is not set when pickerInput() is called so it load the default dependencies that dont work with Bootstrap 5. You may try to set your bslib theme globally with bs_global_set().

Victor

matherealize commented 1 year ago

Thank you for the quick reply! That does sound reasonable, but sadly I could not solve the issue using bs_global_set().

However, after more experimentation I found the simple solution: using bslib::page instead of fluidPage.

Below is actually a slight modification of the working example that breaks it:

library(shiny)
library(bslib)
library(bsicons)
library(shinyWidgets)

# bs_global_set(bs_theme(bootswatch = "minty", version = 5))

ui <- navbarPage(
    title = "Synthetic Symbols System",
    theme = bs_theme(bootswatch = "minty", version = 5),
    collapsible = TRUE, 
    tabPanel(
        title = "Synthesize",
        fluidPage(
            # sidebarLayout(
            fluidRow(
                # sidebarPanel(
                column(
                    width = 3, 
                    accordion(
                        accordion_panel(
                            "slider",
                            sliderInput("slider", "sliderInput()", min = 0, max = 100, value = c(30, 70), step = 20)
                        ),
                        accordion_panel(
                            "slider1", icon = bs_icon("alt"),
                            pickerInput(
                                "hello", "hello", 
                                choices = c("a", "b")
                            )
                        ),
                        id = "acc"
                    )
                ),
                # mainPanel(
                column(
                    width = 9
                )
            )
        )
    )
)

server <- function(input, output) {
    # bs_global_set(bs_theme(bootswatch = "minty", version = 5))

    observe(print(input$acc))
}

shinyApp(ui, server)

It seems the breaking change is switching from sidebarLayout with side and main panel to a fluidPage with fluidrows and columns. I was not aware that this would affect the outcome, so this may explain something. I tried to insert bs_global_set in various places but it did not resolve the issue. (I'm also not familiar with web development, so my usage of bs_global_set may be totally wrong...).

Anyway, replacing the call to fluidPage with bslib::page makes it work again, even though I'm unsure if that is something I should have known. Thanks for the answer, I'll close this one!

matherealize commented 1 year ago

Using bslib::page instead of fluidPage solves the issue.