Can I add an arrow icon to my bsCollapsePanel in R Shiny? - r

Here is a very simple example of two collapsible panels and I would like to add an icon like an arrow or something to show that it is able to collapse.
library(shinyBS)
shinyApp(
ui =
fluidPage(
bsCollapse(id = "collapseExample", open = c("panel 1, panel 2"),
bsCollapsePanel("panel 1", "First panel content",
style = "info"),
bsCollapsePanel("panel 2", "Second panel content",
style = "warning"))
),
server =
function(input, output, session){
}
)
Also if anyone knows a way to change the css styling of the panels (like color, font size, font, text alignment, background color, etc) that would be awesome!

I did it outside Shiny in this fiddle that allows you to experiment with Bootstrap (which is the underlying basis of shinyBS).
I used this CSS.
<style>
.panel-heading .panel-title a.collapsed:after {
transform: rotate(180deg);
transition: .5s ease-in-out;
}
.panel-heading .panel-title a:after {
content:'⏶';
text-align: right;
float:right;
transition: .5s ease-in-out;
}
.panel-heading .panel-title a:not([class]):after {
transform: rotate(180deg);
}
</style>
The CSS uses the :after selector to place an arrow (as content) behind and displays it on the right-hand side of the panel (i.e. float and text-align). The other two specs a:not([class]) and a.collapsed make sure that the arrow always points into the right direction. The transitions are for show.
Place this CSS inside a tags$head element (instructions here) and it should style your panels accordingly. The head of your sample app should look like this:
shinyApp(
ui =
fluidPage(
tags$head(
# Note the wrapping of the string in HTML()
tags$style(HTML("
<!-- PUT THE CSS HERE without the surrounding <style> tag -->
")),
bsCollapse(id = "coll...
I admit I haven't tested it in a Shiny environment (only in the bootstrap fiddle). But since shinyBS is only a wrapper for Bootstrap it should work.

You can also just put a fontawesome icon next to the title "Panel 1" and "Panel 2".
library(shinyBS)
library(shiny)
shinyApp(
ui =
fluidPage(
bsCollapse(
id = "collapseExample", open = c("panel 1, panel 2"),
bsCollapsePanel(
title = div("Panel 1", icon("angle-down")), "First panel content",
style = "info"),
bsCollapsePanel(
title = div("Panel 2", icon("angle-down")), "Second panel content",
style = "warning"))
),
server =
function(input, output, session){
}
)

Related

How to change text colour of links in navbar header AND links in nav pills (in shiny app)?

Here is a redacted version of my shiny app:
library(shiny)
library(bslib)
ui <- tagList(
fluidPage(
titlePanel(""),
tags$head(tags$style(HTML(
"
.navbar-default {
color: red !important;'
}
.navbar-default .navbar-nav > .active > a,
.navbar-default .navbar-nav > li > a:hover {
color: red !important;
}
.navbar-default .navbar-nav > li > a {
color: pink !important;
}
"
))),
navbarPage(
windowTitle = "App Name",
theme = bs_theme(bootswatch = "flatly",
base_font = font_google("Lato"),
primary = "#333F50",
bg = "white",
fg = "#D67540"),
title = "I am the title",
selected = "Main Tab 1",
tabPanel(title = "Main Tab 1",
fluidPage(
sidebarLayout(
sidebarPanel(textInput(inputId = "text_input", label = "Enter text:")),
mainPanel(textOutput(outputId = "text_output"))
)
)
),
tabPanel(title = "Main Tab 2",
fluidPage(
fluidRow(
column(7,
navlistPanel(
tabPanel("Tab 1"),
tabPanel("Tab 2"),
tabPanel("Tab 3"),
widths = c(2, 10),
well = FALSE)
)))
)
)
)
)
server <- function(input, output){
output$text_output <- renderText(input$text_input)
}
shinyApp(ui, server)
Currently the text for "Main Tab 1" and "Main Tab 2" is pink and red when hovered/selected.
I would also like to apply a similar change to "Tab 1", "Tab 2" and "Tab 3" - for these I want the text colour to change from teal to black and from white to orange when hovered/selected.
My understanding is that the !important next to the color value forces all links to inherit the same properties, but I would like different colours for the links in the navbar header and the links in the nav-pills.
I have asked a related question here:
How to change text colour of navbarPage links when hovered on (in shiny app)?
How can I make this change?
Any help is much appreciated :)
Note: Colours are intentionally not aesthetic (just using these for distinction as I'm still learning)
Ok - I've implemented your request, but see both parts of my answer:
Part 1 - The Solution
To implement your requested styles, I did two things:
I changed your navListPanel by inserting it into a tags$div with the class name side_panel. I housed this navlistPanel in a div with a custom class so that the CSS you wanted for the panel didn't bleed into other .nav classes, including the main .nav-header.
tags$div(
navlistPanel(
tabPanel("Tab 1"),
tabPanel("Tab 2"),
tabPanel("Tab 3"),
widths = c(2, 10),
well = FALSE),
class = "side_panel"
)
I then added the following CSS to your tags$style, starting each line with .side_panel to only affect the class we just created:
.side_panel .nav-pills a:hover {
color: black;
background: rgba(253,126,20, 0.8);
}
.side_panel .nav-pills .nav-link.active {
color: black;
background: #fd7e14; /* BS orange */
}
Achieving this result
(Note: "Tab 2" is being hovered over, the screenshot didn't capture my mouse):
Part 2 - Future Styling
As it seems like you're particular about the style of your app (don't worry, I'm obsessive about this type of styling too), you should consider two things.
Rather than inserting all of your CSS at the beginning of your app, consider creating a separate style.css file located in a www folder. This www folder should be in the same directory as your app.R file. You can then inject all of this CSS into your app using shiny::includeCSS("www/style.css") (ref link).
To learn how to stylize custom components of your Shiny apps in the future, you should familiarize yourself with the Inspect feature of your browser. I mostly use bs4Dash in my apps, so I wasn't as familiar with your app's html components. To find the objects and their CSS, I simply inspected the webpage (right click + inspect) and use ctrl+shift+c to click on the tabs and view their CSS. Going one step further, you can change the style of the CSS on the fly by typing in custom values.
Good luck!

Remove shaded background and border of indicators in shinydashboardPlus::carousel

I'm using {shinydashboard} and {shinydashboardPlus} to display a carousel. When I click on the carousel indicators they are displayed with a shaded background and a blue border (this wasn't the case in an earlier version of shinydashboardPlus::carousel, I added the used package versions in the code below). I checked this in Firefox and EDGE Chromium. I want to remove both (box and border) and can't figure out how to tweek the CSS. I did already manage to hide the .carousel-caption, but after playing around some time with the DOM inspector, I've not managed to do the same for the small box around the carousel indicators.
My problem is to identify the class of the object that has the shaded background and the blue border as attributes. Once I figure that out, it should be easy to change it.
Any help appreciated.
# Windows 10 64bit, R 4.1.0
library(shiny) # 1.6
library(shinydashboard) # 0.7.1
library(shinydashboardPlus) # 2.0.3
shinyApp(ui = dashboardPage(
title = "Test",
header = dashboardHeader(),
sidebar = dashboardSidebar(disable = TRUE,
width = "0px",
collapsed = TRUE),
body = dashboardBody(
tags$head(
tags$style(HTML("
.carousel-caption {
display: none !important;
}
"))
),
carousel(
id = "mycarousel",
carouselItem(
caption = "Item 1",
tags$img(src = "https://getbootstrap.com/docs/5.1/assets/img/bootstrap-icons.png")
),
carouselItem(
caption = "Item 2",
tags$img(src = "https://getbootstrap.com/docs/5.1/assets/img/bootstrap-icons.png")
)
)
) # close dashboardBody
), # close dashboardPage
server = function(input, output) {}
)
This is due to the accessibility plugin from bootstrap that the shiny people decided to add in since 1.6. There was no problem before. This is annoying. I tried to ask them to have an option choose load or not to load this plugin on start, but they refused. You can read from this issue.
To fix your problems, I have added some CSS styles:
# Windows 10 64bit, R 4.1.0
library(shiny) # 1.6
library(shinydashboard) # 0.7.1
library(shinydashboardPlus) # 2.0.3
shinyApp(ui = dashboardPage(
title = "Test",
header = dashboardHeader(),
sidebar = dashboardSidebar(disable = TRUE,
width = "0px",
collapsed = TRUE),
body = dashboardBody(
tags$head(
tags$style(HTML("
.carousel-caption {
display: none !important;
}
a.carousel-control:focus {
outline: none;
/*change background-image to none if want to remove black bars on right*/
background-image: linear-gradient(to right, transparent 0px, rgba(0,0,0,0.5) 100%);;
box-shadow: none;
}
a.carousel-control.left:focus {
/*change background-image to none if want to remove black bars on left*/
background-image: linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);
}
.carousel-tablist-highlight.focus {
outline: none;
background-color: transparent;
}
"))
),
carousel(
id = "mycarousel",
carouselItem(
caption = "Item 1",
tags$img(src = "https://getbootstrap.com/docs/5.1/assets/img/bootstrap-icons.png")
),
carouselItem(
caption = "Item 2",
tags$img(src = "https://getbootstrap.com/docs/5.1/assets/img/bootstrap-icons.png")
)
)
) # close dashboardBody
), # close dashboardPage
server = function(input, output) {}
)
The first rule was added by you. The second and third rules are to remove the ugly box when you click left and right bar, but I didn't remove the black shadows around. You can remove them following the instructions I leave as comments. The last rule is what you really want. Only leave the last one if you don't care about left and right bars.

R shiny how to "box" a simple text on a shiny page

I'm using documentation https://shiny.rstudio.com/tutorial/written-tutorial/lesson2/ and more precisely the following code to add a simple paragraph to my shiny page:
ui <- fluidPage(
titlePanel("My Shiny App"),
sidebarLayout(
sidebarPanel(),
mainPanel(
p("p creates a paragraph of text."),
p("A new p() command starts a new paragraph. Supply a style attribute to change the format of the entire paragraph.", style = "font-family: 'times'; font-si16pt"),
strong("strong() makes bold text."),
em("em() creates italicized (i.e, emphasized) text."),
br(),
code("code displays your text similar to computer code"),
div("div creates segments of text with a similar style. This division of text is all blue because I passed the argument 'style = color:blue' to div", style = "color:blue"),
br(),
p("span does the same thing as div, but it works with",
span("groups of words", style = "color:blue"),
"that appear inside a paragraph.")
)
)
)
My goal is to take any of these paragraphs, let's say the last one, and display it like inside a box the same way we can see it here:
http://www.sthda.com/english/articles/40-regression-analysis/168-multiple-linear-regression-in-r/
where it says "library(tidyverse)", this paragraph is inside a box with a different background color.
Does anyone know how I can achieve that?
I don't know much about HTML hence the hard time I'm facing.
Thank you
It's not about HTML it's CSS what you should look for. (;
For example you could copy & paste the CSS styling rules from the webpage you linked into you shiny app (not the recommend way but quick & dirty) to change the appearance of the code tag like so:
library(shiny)
ui <- fluidPage(
tags$head(
tags$style(HTML("
code {
display:block;
padding:9.5px;
margin:0 0 10px;
margin-top:10px;
font-size:13px;
line-height:20px;
word-break:break-all;
word-wrap:break-word;
white-space:pre-wrap;
background-color:#F5F5F5;
border:1px solid rgba(0,0,0,0.15);
border-radius:4px;
font-family:monospace;
}"))),
titlePanel("My Shiny App"),
sidebarLayout(
sidebarPanel(),
mainPanel(
p("p creates a paragraph of text."),
p("A new p() command starts a new paragraph. Supply a style attribute to change the format of the entire paragraph.", style = "font-family: 'times'; font-si16pt"),
strong("strong() makes bold text."),
em("em() creates italicized (i.e, emphasized) text."),
br(),
code("code displays your text similar to computer code"),
div("div creates segments of text with a similar style. This division of text is all blue because I passed the argument 'style = color:blue' to div", style = "color:blue"),
br(),
p("span does the same thing as div, but it works with",
span("groups of words", style = "color:blue"),
"that appear inside a paragraph.")
)
)
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)

Style shinyWidget::dropdownButton in shinydashboard::box header

Background
I am trying to place a shinyWidget::dropdownButton in the header of a shinydashboard::box. The button should have the look and feel of the button created when using a collapsible box (box(..., collapsible = TRUE).
With the help of some JavaScript I was able to move the dropdown, which seemed to me the easier approach rather than constructing all the HTML myself.
The code below does what I want to do, however I am struggling with the css, because the elements in the dropdown are partly white on white (which makes sense I guess because they are (grand) children of class .box-tools)
What I want
I want that all controls in the dropdown look like as if I put the dropdown in the body of the box:
Goal: Dropdown in the body
Current Situation: Dropdown in the header
Questions
How can I achieve this? Which css rules do I have to use, to make sure that any kind of control looks like as if in the body of the box? Could I achieve the same behaviour even easier? (For instance by wrapping all my controls in the dropdown in another element)? I do know my basics in css but here I feel a bit at loss which rules I need to consider to get to the desired result.
Code
library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(shinyjs)
makeDropDown <- function(i) {
dropdownButton(
h3("Heading"),
selectInput(paste0("sel", i), "Select:", LETTERS),
downloadButton(paste0("down", i), "Load"),
circle = FALSE,
icon = icon("cog")
)
}
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
useShinyjs(),
box(solidHeader = TRUE,
status = "info",
title = "Box",
div(
makeDropDown(1),
class = "box-tools pull-right",
id = "moveme"
),
makeDropDown(2)
)
)
)
server <- function(input, output, session) {
runjs("$('.box-header').append($('#moveme').detach())")
}
shinyApp(ui, server)
You're right, some CSS rules are overwritten, you can use some inline CSS with !important to control appearance :
makeDropDown <- function(i) {
dropdownButton(
tags$div(
style = "color: black !important;", # for text
h3("Heading"),
selectInput(paste0("sel", i), "Select:", LETTERS),
downloadButton(
outputId = paste0("down", i), label = "Load",
style = "background-color: #f4f4f4 !important; color: #444 !important; border: 1px solid #ddd !important;" # for button
)
),
circle = FALSE,
icon = icon("cog")
)
}
Otherwise, maybe #DivadNojnarg have a better solution in shinydashboardPlus, I'll ask him !

Adjust height of navbarPage() header in shiny

I would like to adapt the size/height of the navbarPage Menue since it is occupying a lot of space.
I tried working with some CSS style adaption but since I am new to that I am struggling a little bit.
This is how it looks at the moment:
Example Image
And this is the corresponding ui:
shinyUI(fluidPage(
shinyjs::useShinyjs(),
navbarPage(
title = h4(style="text-align:center", "Man vs. Machine"),
tabPanel(h4(style="text-align:center","Voting"),
tags$style("
.col-sm-8 { /* radioButtons is a div class*/
margin-top: 20px;
}"),
fluidRow(column(12,h4("Click the Hydrograph you prefer?")))),
fluidRow(tableOutput("select")),
tabPanel(h4(style="text-align:center","Results"),
fluidRow(column(2, textOutput("value"))),
fluidRow(column(2, textOutput("value2")))))))

Resources