Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find the CSS to modify the highlight of a tabPanel with cicerone

Tags:

css

r

shiny

I'm using the package {cicerone} to create a tour on my shiny app. The problem is that the highlight is completely opaque when the navbar is fixed-top. I searched during hours how to modify the CSS so that the result is the same as when the navbar is static but without success. I asked to the package maintainer but no solution so far.

Navbar with good display:

library(shiny)
library(cicerone)

home_guide <- Cicerone$
  new(id = "homeGuide")$
  step(
    "[data-value='home']",
    "Hello",
    "Hello from tab 1",
    is_id = FALSE
  )$
  step(
    "[data-value='tab']",
    "Text",
    "This is an input",
    is_id = FALSE
  )

ui <- navbarPage(
  "cicerone",
  header = list(use_cicerone()),
  id = "nav",
  # position = "fixed-top",
  tabPanel(
    "home",
    h1("First tab", id = "home_primary"),
    textInput("home_secondary", "Text")
  ),
  tabPanel(
    "tab",
    h1("Second tab", id = "tab_primary"),
    textInput("tab_secondary", "Text")
  )
)

server <- function(input, output, session){
  
  home_guide$init()$start()
  
}

shinyApp(ui, server)

Navbar with bad display (add position = "fixed-top" in the ui):

library(shiny)
library(cicerone)

home_guide <- Cicerone$
  new(id = "homeGuide")$
  step(
    "[data-value='home']",
    "Hello",
    "Hello from tab 1",
    is_id = FALSE
  )$
  step(
    "[data-value='tab']",
    "Text",
    "This is an input",
    is_id = FALSE
  )

ui <- navbarPage(
  "cicerone",
  header = list(use_cicerone()),
  id = "nav",
  position = "fixed-top",
  tabPanel(
    "home",
    h1("First tab", id = "home_primary"),
    textInput("home_secondary", "Text")
  ),
  tabPanel(
    "tab",
    h1("Second tab", id = "tab_primary"),
    textInput("tab_secondary", "Text")
  )
)

server <- function(input, output, session){
  
  home_guide$init()$start()
  
}

shinyApp(ui, server)

Is there an expert in CSS willing to show me how to modify the CSS in the second case so that the result is the same as in the first one? This person can also make a pull request to implement his/her solution in the package.

Note: for now (12 October 2020), you probably need to install the development version of {cicerone} (devtools::install_github("JohnCoene/cicerone")).

like image 493
bretauv Avatar asked Oct 12 '20 19:10

bretauv


2 Answers

the error is caused by making the position: fixed; and looking at the fact that the navbar is the top most element i.e child of the body, and that position : absolute; fixes this on way would be to modify the css

.navbar-fixed-top, .navbar-fixed-bottom{
    position : absolute;
}

However this invalidates the effect of position : fixed;. So a way to do this is by listening for user clicks on the next|previous buttons, to toggle between position fixed and position absolute, this can be done using js and to run js from shiny we need the shinyjs package.

install.packages("shinyjs")
library(shiny)
library(shinyjs)
library(cicerone)

homeGuide <- Cicerone$
  new(id = "homeGuide")$
  step(
    "[data-value='home']",
    "Hello",
    "Hello from tab 1",
    is_id = FALSE
  )$
  step(
    "[data-value='tab']",
    "Tab :(",
    "This is a tab",
    is_id = FALSE
  )$
  step(
    "[data-value='last']",
    "Last",
    "This is the last tab the one we check for",
    is_id = FALSE
  )$
  step(
    "home_secondary",
    "Text",
    "This is an input"
  )

the UI

  • call useShinyjs to import shinyjs javascript libs into the webpage.
  • the next line sets the style by default to position absolute.
ui <- tagList(
  useShinyjs(),
  tags$head(tags$style(HTML("
      .navbar-fixed-top, .navbar-fixed-bottom{
        position : absolute;
      }
  "))),
  navbarPage(
  "cicerone",
  header = list(use_cicerone()),
  id = "nav",
   position = "fixed-top",
  tabPanel(
    "home",
    h1("First tab", id = "home_primary"),
    textInput("home_secondary", "Text")
  ),
  tabPanel(
    "tab",
    h1("Second tab", id = "tab_primary"),
    textInput("tab_secondary", "Text")
  ),
  tabPanel(
    "last",
    h1("last tab", id = "tab_last"),
    textInput("inp_text", "Text")
  )
))

Server :

server <- function(input, output, session){
  homeGuide$init()$start()
  # if the user clicks the next button
  observeEvent(input$homeGuide_cicerone_next, {
    # check if the last highlighted element is the last tab
    if(grepl("last",input$homeGuide_cicerone_next$highlighted) ) runjs("document.querySelector('.navbar').style.position = 'fixed'; document.querySelector('.navbar').style.position") 
# because of some weird glitch you need to call the value of document.querySelector('.navbar').style.position in order for it to be changed took me a day to figure this out
   })
  # now for the previous button
  observeEvent(input$homeGuide_cicerone_previous, {
    # check if the before previous element is the last tab
    # i don't know if this is the way it should behave but apparently shiny is called before the click is sent to js and before previous actually contains the value of the previous element
      if(grepl("last",input$homeGuide_cicerone_previous$before_previous) ) runjs("document.querySelector('.navbar').style.position = 'absolute'; document.querySelector('.navbar').style.position")
   })
}

shinyApp(ui, server)

Note : that changing the z-index above 100002 will push the element above the gray overlay.

like image 137
Abdessabour Mtk Avatar answered Nov 20 '22 06:11

Abdessabour Mtk


This CSS solves the problem (it comes from this comment on the driver.js repo):

div#driver-highlighted-element-stage, div#driver-page-overlay {
  background: transparent !important;
  outline: 5000px solid rgba(0, 0, 0, .75)
}

It is now incorporated in the development version of {cicerone} (to be installed with: devtools::install_github("JohnCoene/cicerone")).

like image 1
bretauv Avatar answered Nov 20 '22 07:11

bretauv