如何根据 rshiny 中的用户输入切换外部 css 文件?
How to switch external css file based on user input in rshiny?
我希望在我的应用程序中构建暗模式。我知道我们可以使用 bs_theme() 来实现,但是我的应用程序在外部 css 文件中有更多设置,当我使用 bs_theme() 时无法读取这些设置。
我想要 2 个单独的 CSS 文件,一个用于浅色主题,一个用于深色主题。根据用户输入,相关的主题文件应该加载到我的 Rshiny 应用程序中。关于如何做到这一点有什么建议吗?
在这种情况下,我会创建两个不同的 css classes。
Here 您将了解如何将 css 文件(随心所欲)添加到闪亮的应用程序中。
要在 类 之间切换,我们可以使用 addCssClass
/ removeCssClass
(或 toggleCssClass
)从 library(shinyjs)
:
library(shiny)
library(shinyjs)
if(!dir.exists("www")){
dir.create("www")
}
writeLines(".dark {
background-color: black;
color: white; /* text color */
}", con = "www/dark_mode.css")
writeLines(".light {
background-color: white;
color: black; /* text color */
}", con = "www/light_mode.css")
ui <- fluidPage(
useShinyjs(),
tags$head(
tags$link(rel = "stylesheet", type = "text/css", href = "dark_mode.css"),
tags$link(rel = "stylesheet", type = "text/css", href = "light_mode.css")
),
radioButtons("mode", "Select mode", choices = c("dark", "light"), selected = "light")
)
server <- function(input, output, session) {
observeEvent(input$mode, {
if(input$mode == "dark"){
addCssClass(class = "dark", selector = "body")
removeCssClass(class = "light", selector = "body")
} else {
addCssClass(class = "light", selector = "body")
removeCssClass(class = "dark", selector = "body")
}
})
}
shinyApp(ui, server)
同样可以通过 Shiny.addCustomMessageHandler and some custom JS using e.g. element.classList.add("myclass");
(see this).
编辑:将addCssClass
应用于不同类的输入:
library(shiny)
library(shinyjs)
if(!dir.exists("www")){
dir.create("www")
}
writeLines(".dark {
background-color: black !important;
color: white; /* text color */
}", con = "www/dark_mode.css")
writeLines(".light {
background-color: white !important;
color: black; /* text color */
}", con = "www/light_mode.css")
ui <- fluidPage(
useShinyjs(),
tags$head(
tags$link(rel = "stylesheet", type = "text/css", href = "dark_mode.css"),
tags$link(rel = "stylesheet", type = "text/css", href = "light_mode.css")
),
radioButtons("mode", "Select mode", choices = c("dark", "light"), selected = "light"),
selectizeInput("Test", "Test Input", choices = 1:10),
actionButton("testButton", "Test Button")
)
server <- function(input, output, session) {
observeEvent(input$mode, {
applyTo <- list(".selectize-input", ".btn-default")
if(input$mode == "dark"){
lapply(applyTo, function(x){
addCssClass(class = "dark", selector = x)
removeCssClass(class = "light", selector = x)
})
} else {
lapply(applyTo, function(x){
addCssClass(class = "light", selector = x)
removeCssClass(class = "dark", selector = x)
})
}
})
}
shinyApp(ui, server)
编辑:使用 forEach
:
library(shiny)
library(shinyjs)
if(!dir.exists("www")){
dir.create("www")
}
writeLines(".dark {
background-color: black !important;
color: white; /* text color */
}", con = "www/dark_mode.css")
writeLines(".light {
background-color: white !important;
color: black; /* text color */
}", con = "www/light_mode.css")
ui <- fluidPage(
useShinyjs(),
tags$head(
tags$link(rel = "stylesheet", type = "text/css", href = "dark_mode.css"),
tags$link(rel = "stylesheet", type = "text/css", href = "light_mode.css")
),
radioButtons("mode", "Select mode", choices = c("dark", "light"), selected = "light"),
selectizeInput("Test", "Test Input", choices = 1:10),
actionButton("testButton", "Test Button")
)
server <- function(input, output, session) {
dm_classes <- paste(c(".selectize-input", ".btn-default"), collapse = ", ")
observeEvent(input$mode, {
if(input$mode == "dark"){
runjs(sprintf("document.querySelectorAll('%s').forEach(x=>x.classList.add('dark'));
document.querySelectorAll('%s').forEach(x=>x.classList.remove('light'));", dm_classes, dm_classes))
} else {
runjs(sprintf("document.querySelectorAll('%s').forEach(x=>x.classList.add('light'));
document.querySelectorAll('%s').forEach(x=>x.classList.remove('dark'));", dm_classes, dm_classes))
}
})
}
shinyApp(ui, server)
假设您的 CSS 文件被命名为 darkmode.css 和 lightmode.css,并且放置在进入 www 子文件夹,您可以像这样使用 renderUI
:
library(shiny)
ui <- fluidPage(
tags$head(
uiOutput("css")
),
radioButtons("select", "Select mode", c("dark", "light"))
)
server <- function(input, output){
output[["css"]] <- renderUI({
cssfile <- paste0(input[["select"]], "mode.css")
tags$link(rel = "stylesheet", type = "text/css", href = cssfile)
})
}
shinyApp(ui, server)
我希望在我的应用程序中构建暗模式。我知道我们可以使用 bs_theme() 来实现,但是我的应用程序在外部 css 文件中有更多设置,当我使用 bs_theme() 时无法读取这些设置。
我想要 2 个单独的 CSS 文件,一个用于浅色主题,一个用于深色主题。根据用户输入,相关的主题文件应该加载到我的 Rshiny 应用程序中。关于如何做到这一点有什么建议吗?
在这种情况下,我会创建两个不同的 css classes。
Here 您将了解如何将 css 文件(随心所欲)添加到闪亮的应用程序中。
要在 类 之间切换,我们可以使用 addCssClass
/ removeCssClass
(或 toggleCssClass
)从 library(shinyjs)
:
library(shiny)
library(shinyjs)
if(!dir.exists("www")){
dir.create("www")
}
writeLines(".dark {
background-color: black;
color: white; /* text color */
}", con = "www/dark_mode.css")
writeLines(".light {
background-color: white;
color: black; /* text color */
}", con = "www/light_mode.css")
ui <- fluidPage(
useShinyjs(),
tags$head(
tags$link(rel = "stylesheet", type = "text/css", href = "dark_mode.css"),
tags$link(rel = "stylesheet", type = "text/css", href = "light_mode.css")
),
radioButtons("mode", "Select mode", choices = c("dark", "light"), selected = "light")
)
server <- function(input, output, session) {
observeEvent(input$mode, {
if(input$mode == "dark"){
addCssClass(class = "dark", selector = "body")
removeCssClass(class = "light", selector = "body")
} else {
addCssClass(class = "light", selector = "body")
removeCssClass(class = "dark", selector = "body")
}
})
}
shinyApp(ui, server)
同样可以通过 Shiny.addCustomMessageHandler and some custom JS using e.g. element.classList.add("myclass");
(see this).
编辑:将addCssClass
应用于不同类的输入:
library(shiny)
library(shinyjs)
if(!dir.exists("www")){
dir.create("www")
}
writeLines(".dark {
background-color: black !important;
color: white; /* text color */
}", con = "www/dark_mode.css")
writeLines(".light {
background-color: white !important;
color: black; /* text color */
}", con = "www/light_mode.css")
ui <- fluidPage(
useShinyjs(),
tags$head(
tags$link(rel = "stylesheet", type = "text/css", href = "dark_mode.css"),
tags$link(rel = "stylesheet", type = "text/css", href = "light_mode.css")
),
radioButtons("mode", "Select mode", choices = c("dark", "light"), selected = "light"),
selectizeInput("Test", "Test Input", choices = 1:10),
actionButton("testButton", "Test Button")
)
server <- function(input, output, session) {
observeEvent(input$mode, {
applyTo <- list(".selectize-input", ".btn-default")
if(input$mode == "dark"){
lapply(applyTo, function(x){
addCssClass(class = "dark", selector = x)
removeCssClass(class = "light", selector = x)
})
} else {
lapply(applyTo, function(x){
addCssClass(class = "light", selector = x)
removeCssClass(class = "dark", selector = x)
})
}
})
}
shinyApp(ui, server)
编辑:使用 forEach
:
library(shiny)
library(shinyjs)
if(!dir.exists("www")){
dir.create("www")
}
writeLines(".dark {
background-color: black !important;
color: white; /* text color */
}", con = "www/dark_mode.css")
writeLines(".light {
background-color: white !important;
color: black; /* text color */
}", con = "www/light_mode.css")
ui <- fluidPage(
useShinyjs(),
tags$head(
tags$link(rel = "stylesheet", type = "text/css", href = "dark_mode.css"),
tags$link(rel = "stylesheet", type = "text/css", href = "light_mode.css")
),
radioButtons("mode", "Select mode", choices = c("dark", "light"), selected = "light"),
selectizeInput("Test", "Test Input", choices = 1:10),
actionButton("testButton", "Test Button")
)
server <- function(input, output, session) {
dm_classes <- paste(c(".selectize-input", ".btn-default"), collapse = ", ")
observeEvent(input$mode, {
if(input$mode == "dark"){
runjs(sprintf("document.querySelectorAll('%s').forEach(x=>x.classList.add('dark'));
document.querySelectorAll('%s').forEach(x=>x.classList.remove('light'));", dm_classes, dm_classes))
} else {
runjs(sprintf("document.querySelectorAll('%s').forEach(x=>x.classList.add('light'));
document.querySelectorAll('%s').forEach(x=>x.classList.remove('dark'));", dm_classes, dm_classes))
}
})
}
shinyApp(ui, server)
假设您的 CSS 文件被命名为 darkmode.css 和 lightmode.css,并且放置在进入 www 子文件夹,您可以像这样使用 renderUI
:
library(shiny)
ui <- fluidPage(
tags$head(
uiOutput("css")
),
radioButtons("select", "Select mode", c("dark", "light"))
)
server <- function(input, output){
output[["css"]] <- renderUI({
cssfile <- paste0(input[["select"]], "mode.css")
tags$link(rel = "stylesheet", type = "text/css", href = cssfile)
})
}
shinyApp(ui, server)