Colors next to checkboxes in Shiny

This is a screenshot from the Scots Syntax Atlas
Screen Shot 2020-07-30 at 16.27.51

I'm trying to create a similar feature on a leaflet map in Shiny, where there are colored icons next to each checkbox that match the points on the map. Sort of like a combination checkbox/legend.

Shiny Widgets has some checkbox styling options, but they all change the styling of the actual checkbox, whereas I'd like to insert icons/colors next to the checkbox. The closest thing I've found is something like what's mentioned here, where the user wanted to use an image as an option for a radio button/checkbox, but it would be absolutely wonderful if there were some way to integrate this with the color-coding of the points on the leaflet map (since I've already specified those colors in the leaflet palette) instead of having to e.g. create png swatches of each color and manually include them in the code.

Does anyone have resources/leads they can point me to on this? Any idea if it's possible?

Thank you!

1 Like

here is a start

library(shiny)
library(htmltools )
ui <- fluidPage(
  div(  htmlDependency("font-awesome", 
                       "5.13.0", "www/shared/fontawesome", package = "shiny", 
                       stylesheet = c("css/all.min.css", "css/v4-shims.min.css")),
    p("some text"),
    radioButtons(inputId = "mybuttons",
                 label="styled choices",
                 choiceNames = list(HTML('<div style="display:flex"><i class="fa fa-circle"
                                         style="color:lightblue;"></i><div style="color:black;">1</div></div>'),
                                    HTML('<div style="display:flex"><i class="fa fa-circle"
                                         style="color:blue;"></i><div style="color:black;">2</div></div>'),
                                    HTML('<div style="display:flex"><i class="fa fa-circle"
                                         style="color:darkblue;"></i><div style="color:black;">3</div></div>')),
                 choiceValues= letters[1:3])
)
)

server <- function(input, output, session) {

}

shinyApp(ui, server)
2 Likes

This looks like a great start. I'll play around with it.

Thank you very much!

Thanks again, @nirgrahamuk. Your example works!

Just a minor formatting question that maybe you or someone else can help with: in your original example, the dots and labels showed up at different heights than the check boxes, like this:
Screen Shot 2020-07-31 at 08.54.52

I added margin-top:3px; after e.g. color:lightblue; which fixed the height of the dots nicely:
Screen Shot 2020-07-31 at 08.55.03

But the text labels are still not aligned. Playing around with margin-top and margin-bottom for the text labels didn't do anything. Sorry if this is obvious--I haven't worked with html before. Do you know how I might fix the alignment?

Reprex is here (lightly modified from your original)

library(shiny)
library(htmltools )
ui <- fluidPage(
  div(  htmlDependency("font-awesome", 
                       "5.13.0", "www/shared/fontawesome", package = "shiny", 
                       stylesheet = c("css/all.min.css", "css/v4-shims.min.css")),
        p("some text"),
        checkboxGroupInput(inputId = "mybuttons",
                     label="styled choices",
                     choiceNames = list(HTML('<div style="display:flex"><i class="fa fa-circle"
                                         style="color:lightblue;margin-top:3px;"></i><div style="color:black;padding:5px;">1</div></div>'),
                                        HTML('<div style="display:flex"><i class="fa fa-circle"
                                         style="color:blue;margin-top:3px;"></i><div style="color:black;padding:5px;">2</div></div>'),
                                        HTML('<div style="display:flex"><i class="fa fa-circle"
                                         style="color:darkblue;margin-top:3px;"></i><div style="color:black;padding:5px;">3</div></div>')),
                     choiceValues= letters[1:3],
                     selected = letters[1:3])
  )
)

server <- function(input, output, session) {
  
}

shinyApp(ui, server)

the padding you added is to all direction, to specify only left padding make it
padding-left:5px;

Wow, thank you so much! I thought you were missing my point about the vertical alignment, but then I went back and actually tried your padding fix, and voilà, it fixes the problem.

Thank you for your patience and solution--this really makes my day!

1 Like

if you plan to reuse this approach it can make your code more elegant to further seperate out the commonly repeated parts like

library(shiny)
library(htmltools )
list_content <- function(col,content)
{
paste0('<div style="display:flex"><i class="fa fa-circle"
                                         style="color:',col,';margin-top:3px;"></i><div style="color:black;padding-left:5px;">',content,'</div></div>')

}
ui <- fluidPage(
  div(  htmlDependency("font-awesome", 
                       "5.13.0", "www/shared/fontawesome", package = "shiny", 
                       stylesheet = c("css/all.min.css", "css/v4-shims.min.css")),
        p("some text"),
        checkboxGroupInput(inputId = "mybuttons",
                           label="styled choices",
                           choiceNames = list(HTML(list_content("lightblue","1")),
                                              HTML(list_content("blue","2")),
                                              HTML(list_content("darkblue","3"))),
                           choiceValues= letters[1:3],
                           selected = letters[1:3])
  )
)

server <- function(input, output, session) {
  
}

shinyApp(ui, server)

For sure. That was going to be my next step :slight_smile: