Let's say I want to reduce the padding between the left edge of the screen and the first column to maximize real estate on an iPhone. Here's the table:
library(shiny)
library(reactable)
ui <- fluidPage(
theme = "styles.css",
mainPanel(
align = "left",
reactableOutput("table")
)
)
server <- function(input, output, session) {
output$table <- renderReactable({
reactable(iris,
fullWidth = FALSE
)
})
}
shinyApp(ui, server)
And styles.css is:
.container-fluid {
padding-left: 0 !important;
}
This does not work. However, if I use Chrome Inspector to look at the gap, I can manually set padding-left: 0 and the gap narrows.
How do I narrow the gap from within R/Shiny//css?
Check in the inspector in the sources tab if the file is being correctly included. If it still does not work check if there are errors in your css file, that might be preventing the stylesheet from working. Finally, you might have to set the style inline or in the style tag. If you are using Bootstrap then you can use the ml-0 class in the container.
Related
I thought I could set a class for the value box to remove padding like this:
bslib::value_box("test", "test", class = "p-0")
Or in a minimal Shiny app:
library(shiny)
ui <- fluidPage(
theme = bslib::bs_theme(version = 5),
bslib::value_box("test", "test", class = "p-0")
)
server <- function(input, output, session) {
}
shinyApp(ui, server)
But if I do that, it removes only the padding for the bootstrap card:
I want to remove all the blue padding around the content, including the bootstrap card body.
The problem appears to be that bslib::value_box() function wraps content with bslib::card_body_fill(), and it doesn't look like there is a way to pass arguments through to card_body_fill().
I can go into developer tools and search for "padding" and accomplish this:
Or I can add some CSS:
.card-body {
padding: 0;
}
But this will change the padding for all elements with class card_body. What if I want to target only a few value boxes?
Add a class (suppose nopad) to value_boxes for which you want to remove the padding of the content. Using developer tools, you would see that value_box contents are wrapped within a div with class .value-box-area. So Change the padding for css selector div.nopad .value-box-area.
library(shiny)
ui <- fluidPage(
theme = bslib::bs_theme(version = 5),
# css styles -------------------------------------------
tags$head(
# Note the wrapping of the string in HTML()
tags$style(HTML("
div.nopad .value-box-area {
padding: 0;
}
"))
),
# ------------------------------------------------------
bslib::value_box("test", "test", class = "p-0 nopad"), # with class nopad
bslib::value_box("test", "test", class = "p-0")
)
server <- function(input, output, session) {
}
shinyApp(ui, server)
I'm trying to adjust the positioning of conditionally-rendered objects in R shiny. When running the below skeleton code and clicking the "Delete" action button, I'd like to nudge the conditionally-rendered text ("Select series to delete >>") a bit to the right, and move the little selectInput() box that also conditionally appears on the far right a bit to the left, closer to "Select series to delete >>". I've fiddled with column widths, etc., and I've exhausted all the formatting options which I know of which are limited. Any suggestions for fine-tuning the positioning of these items? My guess is this would entail some CSS which I know almost nothing about.
Skeleton code:
library(dplyr)
library(shiny)
library(shinyjs)
toggleView <- function(input, output_name){
observeEvent(input$delSeries, {show(output_name)})
observeEvent(input$addSeries, {hide(output_name)})
}
ui <- fluidPage(br(),
useShinyjs(),
fluidRow(
column(1,actionButton("addSeries", "Add",width = '70px')),
column(1,actionButton("delSeries","Delete",width = '70px')),
column(3,h5((hidden((textOutput("delFlag")))))),
column(3,hidden(uiOutput("delSeries2")))
)
)
server <- function(input, output, session) {
output$delFlag <- renderText("Select series to delete >>")
output$delSeries2 <-
renderUI(
selectInput("delSeries3",
label = NULL,
choices = c(""),
selected = "",
width = '110px')
)
toggleView(input,"delSeries2")
toggleView(input,"delFlag")
}
shinyApp(ui,server)
You can add some styles to the 2 columns like so:
library(dplyr)
library(shiny)
library(shinyjs)
toggleView <- function(input, output_name){
observeEvent(input$delSeries, {hide(output_name)})
observeEvent(input$addSeries, {show(output_name)})
}
# (0)
css <- HTML("
.row .nudge-right {
padding-right:0;
}
.row .nudge-left {
padding-left:0;
}
")
ui <- fluidPage(
tags$head(tags$style(css)), # (1)
br(),
useShinyjs(),
fluidRow(
column(1,actionButton("addSeries", "Add",width = '70px')),
column(1,actionButton("delSeries","Delete",width = '70px')),
column(3,h5(hidden(textOutput("delFlag"))),
class = c("nudge-right", "text-right")), # (2)
column(3,hidden(uiOutput("delSeries2")), class = "nudge-left") # (2)
)
)
Explanation
The white space you see is partly due to the width of the column and partly due to the so called padding (an additional white space around the element). To bridge this gap you can:
Right align the text. Here you can rely on the already pre-defined (by the underlying bootstrap framework) class text-right.
Further decrease the gap by removing the right padding from the text column and the left padding from the input column. In order to so, you define new classes (I called them .nudge-right and .nudge-left respectively) where you deliberately set the padding to your liking (here I removed it completely, you may want to provide a small offset though - e.g. 5px).
Then all which is left is to
Create some css with the class definitions (#0)
Load the css (#1)
Assign the classes to the columns (#2)
I am building a Shiny app where I want to add some italic text in the navbarPage at the right side. According to the question: Shiny NavBar add additional info I wrote the following code, but it doesn't work out for me:
This is some demo code I have now:
ui <- fluidPage(
navbarPage(theme = shinytheme("flatly"), collapsible = TRUE,
HTML('<a style="text-decoration:none;cursor:default;color:#FFFFFF;" class="active" href="#">Dashboard</a>'), id="nav",
navbarMenu('Graphs', icon = icon('chart-area'),
tabPanel('One country'),
tabPanel('Two countries')),
tabPanel('Tables'),
tags$script(HTML("var header = $('.navbar> .container-fluid');
header.append('<div style=\"float:right\"><h5>Some very important text</h5></div>');
console.log(header)"))
))
server <- function(input, output, session) {}
shinyApp(ui = ui, server = server)
This results in:
the following warning message: Warning message:
Navigation containers expect a collection of bslib::nav()/shiny::tabPanel()s and/or bslib::nav_menu()/shiny::navbarMenu()s. Consider using header or footer if you wish to place content above (or below) every panel's contents.
not the desired output. Because, the text is not visible, because it has the same colour as the background, the text is under the Dashboard, Graphs en tables text, but I want them to be on the same line. The text is not in italic.
Output now
This is what I want:
Desired output
After the answer from lz100 it looks very nice on a big screen, but the text is still under the Dashboard, Graphs en tables text. And when I change the format of the Rshiny dashboard to my very small laptopscreen, the output becomes likes this:
Output after answer from lz100
library(shiny)
library(shinythemes)
ui <- fluidPage(
navbarPage(theme = shinytheme("flatly"), collapsible = TRUE,
HTML('<a style="text-decoration:none;cursor:default;color:#FFFFFF;" class="active" href="#">Dashboard</a>'), id="nav",
navbarMenu('Graphs', icon = icon('chart-area'),
tabPanel('One country',
tags$script(HTML(
"
var header = $('.navbar> .container-fluid');
header.append('<div id=\"my-title\">Some very important text</div>');
")),
tags$style(HTML(
'
.navbar-collapse.collapse {display: inline-block !important;}
#my-title {
float:right;
display: flex;
color: white;
align-items: flex-end;
justify-content: flex-end;
height: 60px;
font-style: italic;
}
'
))
),
tabPanel('Two countries')),
tabPanel('Tables')
)
)
server <- function(input, output, session) {}
shinyApp(ui = ui, server = server)
The reason you have warnings is because you put tags$script under navbarPage. Not a big deal to me, but I relocate your script inside the first tabPanel, warnings are gone.
Some CSS and JS added to create your desired output
Search/Read here if you don't know how these CSS work: https://www.w3schools.com/css/default.asp
While building a very nice additional functionality into my shiny app where the user can reorganize the plots inside the page, I ran into 1 problem.
I noticed that the spacing between the div elements that are being relocated (sorted), changes while doing so, resulting in a misalignment of the plots afterwards.
I have tried to adjust margin values to nothing, 0 or a certain amount of pixels, but that doesn't seem to solve this.
The app that I made to test / illustrate the issue is posted below, where I left out the plots to simplify it:
require('shiny')
require('shinyjqui')
ui <- fluidPage(
div(uiOutput('multiobject'), style = 'width: 1200px')
)
server <- function(input, output, session) {
output$multiobject <- renderUI({
plot_output_list <- list();
for(i in 1:8) {
plot_output_list <- append(plot_output_list,list(
wellPanel(
actionButton('drag', label = icon('hand-point-up'), style = 'float: right; color: #339fff;'),
style = 'border-color:#339fff; border-width:1px; background-color: #fff;display: inline-block; margin:2px; width:290px; height:250px')
))
}
jqui_sortable(do.call(function(...) div(id="allplots", ...), plot_output_list), options = list(handle = '#drag', cancel = ""))
})
}
shinyApp(ui, server)
and this image shows the problem after sorting:
A second problem is the white space appearing when hovering a plot.
I tried to add the css from this "non-R-Shiny" question but could't make it work.
It is not perfect yet, but it should be better than before.
The spacing problem of the <div>s was caused by empty text knods. You can see them when inspecting the page in a browser. This means, changing the css margin arguments will not help. The empty text knods are present in the initial page and once you start dragging they disappear leading to said spacing problem. I got rid of them by not wrapping uiOutput('multiobject') in a div()-tag and instead defined its width using the .ui-sortable class in css.
Your second problem, the white space appearing when hovering a plot, can be mitigated by adding 'float: left; to the style = argument in the for loop of your plot_output_list. The css arguments from the SO post you linked won't work, since there are no classes named .sort-container and .item-wrapper this was specific to the original question. There is still a white space appearing when dragging, but it is much smaller than before.
Update I had some issues with the code, sometimes it's working sometimes not. I think there might be css confilcts. I now added !important to the changed css arguments and it seems to work. Will try it on a different machine later.
require('shiny')
require('shinyjqui')
require('stringr')
ui <- fluidPage(
# Custom CSS----------
tags$style(HTML(".ui-sortable {
width: 1200px !important;
} "
)),
uiOutput('multiobject')
)
server <- function(input, output, session) {
output$multiobject <- renderUI({
print(input$drag)
plot_output_list <- list();
for (i in 1:8) {
plot_output_list <- append(plot_output_list,list(
wellPanel(
actionButton('drag', label = icon('hand-point-up'), style = 'float: right; color: #339fff;'),
style = 'float:left !important; border-color:#339fff; border-width:1px; background-color: #fff;display: inline-block; margin:2px; width:290px; height:250px')
))
}
jqui_sortable(do.call(function(...) div(id = "allplots", ...), plot_output_list), options = list(handle = '#drag', cancel = ""))
})
}
shinyApp(ui, server)
I want to change the height of the select dropdown in shiny app. The default height displays about 8 options, I would like to see more. It is possible to increase the number of options by decreasing the line height of dropdown, but that is not an optimal solution for me. I searched a lot about how to do it, looked into selectize.js code and my current hypothesis is that either this is trivial, or impossible by design.
What I've learned is that the displayed dropdown from select is a div of class .selectize-dropdown-content, but changing its height and width attributes does not change anything. It is possible to change the background color though. Here is my single file shiny app code:
server <- function(input, output) {
output$distPlot <- renderPlot({
plot(0.5,0.5,xlim=c(0,1),ylim=c(0,1))
text(0.5,0.5,input$Letter)
})
}
ui <- shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
selectizeInput("Letter", "", setNames(letters,letters),selected="a",multiple=FALSE),
tags$style(type='text/css',
".selectize-dropdown-content {
height: 600 px;
width: 700 px;
background-color: #b0c4de;
}")
),
mainPanel(plotOutput("distPlot"))
)
))
shinyApp(ui = ui, server = server)
So my question is, whether I am modifying the css of the correct element, or is changing of dropdown height is not possible in selectize.js?
Got the solution, few minutes after posting the question. The height of select dropdown is controlled by max-height attribute. The following css does the trick:
tags$style(type='text/css', ".selectize-dropdown-content {max-height: 400px; }"),