Horizontal Rule hr() in R Shiny Sidebar - css

You can normally make a horizontal rule under UI elements with hr() when using fluidRow() in Shiny, but you can't do it in a sideBarPanel() under text. How can I make a horizontal rule, or something else like it, to divide text and UI elements in my sidebar?

In general the line is visible, but with very low contrast to the background.
To make the line more visible you can modify the CSS code by including the following in the ui part:
tags$head(
tags$style(HTML("hr {border-top: 1px solid #000000;}"))
),
with tags$style(HTML(...)) you can include CSS in your app. The html tag for the line is hr. And the remaining parameter indicate specification of line choice, width, color, etc.
For a full working example see below:
library(shiny)
ui <- fluidPage(
tags$head(
tags$style(HTML("hr {border-top: 1px solid #000000;}"))
),
sidebarLayout(
sidebarPanel(
"text",
hr(),
uiOutput("out")
),
mainPanel(
plotOutput("distPlot")
)
)
)
server <- function(input, output) {
output$out <- renderUI({
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 30)
})
}
shinyApp(ui = ui, server = server)
Update 12.2020:
Comment from David Ranzolin, see comment section.
You can also pass a style argument to hr() directly, e.g.: hr(style = "border-top: 1px solid #000000;")

Related

Make a navigation list panel taller in shiny

Here is a simple example of a navigation list panel:
library(shiny)
ui <- fluidPage(
titlePanel("Navlist panel example"),
navlistPanel(
"Header",
tabPanel("First",
h3("This is the first panel")),
tabPanel("Second",
h3("This is the second panel")),
tabPanel("Third",
h3("This is the third panel"))
)
)
server <- function(input, output) {
}
shinyApp(ui, server)
I need the well (AKA the grey rectangle with rounded corners that is around the navigation list) to be taller and expand to take the white space marked by the red rectangle:
Image
There is no argument in the navlistPanel() function to do this (there is only the width argument)
I would go with something as follow, adding a style tag and adding custom height to the .row element.
library(shiny)
ui <- fluidPage(
titlePanel("Navlist panel example"),
tags$style(".row{height: 500px;} .row div:nth-child(1){height: 100%;}"),
navlistPanel(
"Header",
tabPanel("First",
h3("This is the first panel")),
tabPanel("Second",
h3("This is the second panel")),
tabPanel("Third",
h3("This is the third panel"))
)
)
server <- function(input, output) {
}
shinyApp(ui, server)
PS: be aware that you can have multiple rows in your app

Removing up/down arrows from numericInput() R Shiny

I am interested in removing or hiding the side arrows that appear when you use numericInput() with shiny. I will attach an image of the arrows that I am referring to so everyone can understand which part I would like to remove/hide. After reading the documentation, it does not appear that there is an option to remove these arrows. So I am wondering if there is a way to use CSS to remove these arrows. I did see one other post that asked a similar question. However, I am only interested in using numericInput().
I will attach some sample code. The code essentially does nothing but it will give you a reproducible example.
library(shiny)
server <- function(input, output){
}
ui <- fluidPage(
titlePanel("Test1"),
sidebarLayout(
sidebarPanel(
numericInput("n",
label = h4("Test2"),
min=1,
value = 20),
numericInput("x",
label = h4("Test3"),
min=0,
value = 10),
h4(textOutput("pvalue"))
),
mainPanel(
plotOutput("nullplot")
)
)
)
shinyApp(ui = ui, server = server)
runApp()
WARNING: I have read online that the side arrows do not show up on all web browsers and some versions of RStudio. See here
It does not appear that there is a way to remove the arrows from a numericInput(), however, there is a way to hide them. Just to be clear there is a difference between removing and hiding. Removing the arrows, in theory, should completely remove the code for the arrows. Hiding the arrows will simply mask the code for the side arrows, however, the code will still be present but will not be seen by the user unless they inspect the page.
Below is CSS that can be used to hide the side arrows from numericInput().
tags$head(
tags$style(HTML("
input[type=number] {
-moz-appearance:textfield;
}
input[type=number]::{
-moz-appearance:textfield;
}
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
"))
)
If you wanted to apply this code to the example given in the question, then you could do something like this
library(shiny)
server <- function(input, output){
}
ui <- fluidPage(
titlePanel("Test1"),
sidebarLayout(
sidebarPanel(
tags$head(
tags$style(HTML("
input[type=number] {
-moz-appearance:textfield;
}
input[type=number]::{
-moz-appearance:textfield;
}
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
"))
),
numericInput("n",
label = h4("Test2"),
min=1,
value = 20),
numericInput("x",
label = h4("Test3"),
min=0,
value = 10),
h4(textOutput("pvalue"))
),
mainPanel(
plotOutput("nullplot")
)
)
)
shinyApp(ui = ui, server = server)
runApp()
Overall this is just a workaround because there is no option to remove the side arrows.

Possible to show messageItem in shiny navbarPage?

Similar to the dropdownMenu and messageItem functions which are available in shinydashboard I would like to show message items on the right hand side of the navbar in a navbarPage based app. Example of the related functions here: https://rstudio.github.io/shinydashboard/structure.html
I have tried inserting the same funcitons into a navbarPage app but it is not working as expected- not right aligned.
As a very basic reproducible example, this is the structure of my app with my attempt at including the message item:
library(shiny)
library(shinydashboard)
ui <- shinyUI(
navbarPage("Navbar!",
tabPanel("Plot",
sidebarLayout(
sidebarPanel(),
mainPanel()
)
),
tabPanel(
dropdownMenu(type = "messages",
messageItem(
from = "Sales Dept",
message = "Sales are steady this month."
)
)
)
)
)
server = function(input, output) { }
shinyApp(ui = ui, server = server)
I'm not the best at css, but this is a start to getting the result you're looking for. Change the UI to:
ui <- shinyUI(
fluidPage(
tags$head(
tags$style(HTML("
.navbar-nav .messages-menu a {padding-top: 0px; padding-bottom:0px}
.navbar-nav {width: 90%}
.navbar-nav .messages-menu {float: right; padding-top: 25px;}
"))
),
navbarPage("Navbar!",
tabPanel("Plot",
sidebarLayout(
sidebarPanel(),
mainPanel()
)
),
tabPanel(
dropdownMenu(type = "messages",
messageItem(
from = "Sales Dept",
message = "Sales are steady this month."
)
)
)
)
)
)
The width sets the class navbar-nav to 90% of the width of the screen since it is the space that contains both tab panels but not the label "Navbar!", and the second line takes the class messages-menu within navbar-nav and shifts it to the right of the space filled by navbar-nav (hence why we had to extend the width to include all of the header not occupied by the label; this percentage would likely have to change depending on the text input that is in place of "Navbar!").

Shiny selectInput CSS affecting all selectInputs

I have the following css above a selectizeInput so that selected items are coloured alternatively making for better readability.
tags$style(HTML(".item:nth-child(odd) {background: #F4F4F4 !important;
width: 100% !important;}
.item:nth-child(even) {background: white !important;
width: 100% !important;}"))
Unfortunately it is affect all other selectizeInputs and selectInputs no matter where on the dashboard they appear.
How can I have the above css only apply to the one selectizeInput.
Thanks
I think getting the CSS to select the proper <div> is the trick. Here's a reproducible example of the functionality using the default Shiny scaffolding:
library(shiny)
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("Control CSS of Singl Selectize Input"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
tags$style(HTML("#bins+ .selectize-control.multi .selectize-input > .item:nth-child(odd) {background: #F4F4F4 ;
width: 100% !important;}
#bins+ .selectize-control.multi .selectize-input > .item:nth-child(even) {background: white ;
width: 100% !important;}")),
selectizeInput("bins",
"Number of bins:",
choices = c(1:50),
selected = 30,
multiple = TRUE),
selectizeInput("newbins",
"Number of bins:",
choices = c(1:50),
selected = 30,
multiple = TRUE)
),
# Show a plot of the generated distribution
mainPanel(
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output) {
}
# Run the application
shinyApp(ui = ui, server = server)
The CSS first finds the right id then finds the correct div below that using class. More info on the + sign in CSS: https://www.w3schools.com/cssref/sel_element_pluss.asp

Change button color in Shiny while using navbar

My goal is to change the color of an actionButton in Shine sidebar. In my dashboard content is organized using navbarPage.
I found different solutions, for example:
Using the style argument in actionButton: See here
Using tags directly: See here
These both work great, but as soon as I add a navbar to the dashboard they stop working. The only thing changing color seems to be the border of the button instead of the whole background.
Below a reproducible example.
This works
library(shiny)
shinyApp(
ui = fluidPage(
titlePanel("Styling Action Button"),
sidebarLayout(
sidebarPanel(
h4("Default CSS styling"),
# default styling
actionButton('downloadData1', label= 'Download 1'),
tags$hr(),
actionButton("download1", label="Download with style", class = "butt1"),
# style font family as well in addition to background and font color
tags$head(tags$style(".butt1{background-color:orange;} .butt1{color: black;} .butt1{font-family: Courier New}"))
),
mainPanel()
)
),
server = function(input, output){}
)
This doesn't work
library(shiny)
shinyApp(
ui = fluidPage(
navbarPage("Test multi page",
tabPanel("test",
titlePanel("Styling Action Button"),
sidebarLayout(
sidebarPanel(
h4("Default CSS styling"),
# default styling
actionButton('downloadData1', label= 'Download 1'),
tags$hr(),
actionButton("download1", label="Download with style", class = "butt1"),
# style font family as well in addition to background and font color
tags$head(tags$style(".butt1{background-color:orange;} .butt1{color: black;} .butt1{font-family: Courier New}"))
),
mainPanel()
)
))),
server = function(input, output){}
)
This doesn't work either
library(shiny)
shinyApp(
ui = fluidPage(
navbarPage("Test multi page", theme = shinytheme("cerulean"),
tabPanel("test",
titlePanel("Styling Download Button"),
sidebarLayout(
sidebarPanel(
h4("Default CSS styling"),
# default styling
actionButton('downloadData1', label= 'Download 1'),
actionButton("download1", label="Download with style",
style="color: #fff; background-color: #337ab7")
),
mainPanel()
)
))),
server = function(input, output){})
Referring to your third example, the following works if you don't use shinythemes:
actionButton("download1", "Download with style", style = "color: white; background-color:#4682b4")
You can change color according to your choice. style will change button text color and background-color will change button color using HTML HEX code. You can get any HEX code here: http://htmlcolorcodes.com/

Resources