JohnCoene / cicerone

🏛️ Give tours of your Shiny apps
https://cicerone.john-coene.com
Other
192 stars 7 forks source link

Couple of issues after moving from rintrojs #3

Open federicomarini opened 4 years ago

federicomarini commented 4 years ago

Hey John,

together with @csoneson and @mikelove, we are building a small package/app for exploring model matrices (https://github.com/csoneson/ExploreModelMatrix).

We have had till now some very nice experiences with rintrojs, but I could not resist giving cicerone a spin.

On the marcotullio branch - https://github.com/csoneson/ExploreModelMatrix/tree/marcotullio - I put together a MRE for having the tour given by cicerone.

I have noticed a couple of details that could be decisive in the choice of the backend:

Excited to see if these things are doable - thank you in advance for any help!

JohnCoene commented 3 years ago

Better late than never?

I pushed a fix to the MathJax porblem: example

Sorry it took me so long to get to it.

federicomarini commented 3 years ago

Hi John, thanks for providing a fix to this! And yes, definitely much better late then never 😉 !

I've seen @etiennebacher did provide a nice fix also for rintrojs, so I guess I owe a double thanks here!

What could be a workaround for having elements "anchored" just in the middle of the screen (say, the welcome element of the tour)?

Federico

etiennebacher commented 3 years ago

I didn't see a feature like that in driver.js and it doesn't seem really active now so I don't think this will be added to driver.js. Maybe it is possible to add that separately in cicerone. In case it helps, intro.js or shepherd.js enable anchoring elements in the center of the screen.

federicomarini commented 3 years ago

Exactly, I have been accustomed to what introjs was delivering (with the rintrojs port from Carl Ganz). If it happens to be added here in cicerone, I'll be more than happy to test it out again in our apps!

etiennebacher commented 3 years ago

I have been looking for a way to display a popup that doesn't highlight any specific element, for an introduction popup for example. I found some helpful stuff in a issue of the driver.js repo. I could make it work in a raw HTML document but I couldn't find a way to adapt it in cicerone. I just don't know javascript enough to do that. So @JohnCoene (or someone else fluent in JS), if it helps, here's an example that works in raw HTML.

<!DOCTYPE html>
<html lang="en">
  <head>      
      <!-- Files for driver.js --> 
      <script src="https://unpkg.com/driver.js/dist/driver.min.js"></script>
      <link rel="stylesheet" href="https://unpkg.com/driver.js/dist/driver.min.css">
  </head>

  <body>

    <button id="btn">launch driver.js</button>
    <p id="text-to-highlight">some text that will be highlighted</p>

    <script>
      // The "welcome" popup is assigned to the whole body, which hides 
      // the other elements when it is highlighted. Therefore, this 
      // function removes the highlighting, but only when the body is 
      // the element to highlight
       let orphanCheck = function (e) {
          e.stage.node.style.display = (e.node == document.body) ? 'none' : 'block';
       }
       const driver = new Driver({
         onHighlighted : orphanCheck
       });

       driver.defineSteps([
        {
           element: 'body',
            popover: {
              title: 'Welcome on this page',
              position: 'mid-center'
            }
           },
            {
            element: '#text-to-highlight',
            popover: {
              title: 'The text is highlighted',
              position: 'bottom'
            }
           }
         ]);

         let btn = document.querySelector('#btn');
         btn.addEventListener('click', function(){
          event.stopPropagation(); // necessary to make "launch" button work
          driver.start(); 
         });

         </script>

  </body>
</html>
JohnCoene commented 3 years ago

Does this help? As far as I can tell it's a reproduction of what you shared.

devtools::load_all()

guide <- Cicerone$
  new(allow_close = FALSE)$
  step(
    "body",
    "Observations",
    "Number of observations to draw distribution",
        # cicerone expects an ID to create selector
        # to create #id
        # this switches it off, we don't want #body
        is_id = FALSE,
        # we can pass functions here.
        on_highlighted = "function(e){
            e.stage.node.style.display = (e.node == document.body) ? 'none' : 'block';
        }"
  )

library(shiny)

ui <- fluidPage(
  use_cicerone(),
  plotOutput("hist"),
  actionButton("guide", "Guide")
)

server <- function(input, output){

  guide$
    init()

  output$hist <- renderPlot({
    hist(runif(20))
  })

  observeEvent(input$guide, {
    guide$start()
  })
}

shinyApp(ui, server)

The problem increasingly seem to come from driver.js to be honest. We can solve these things but it makes for a clunky API that I don't like.

If you know of a better library that would allow building tours such as driver.js I'm more than happy to collaborate.

JohnCoene commented 3 years ago

I think we could use popper.js or tippy.js to create something custom with which we could have much more flexibility and respond to such queries.

etiennebacher commented 3 years ago

Does this help? As far as I can tell it's a reproduction of what you shared.

It is not exactly the same because there should be a dark filter behind the popup. I can manually correct it in the inspector by adding background: #000 !important to div#driver-page-overlay but I don't know why it is not the case at the beginning. Adding this in custom.css doesn't change anything.

driver.js (good)

driver-raw

cicerone (not good)

(Note that I just added position = "mid-center" in your example.)

driver-cicerone

If you know of a better library that would allow building tours such as driver.js I'm more than happy to collaborate.

I know that shepherd.js is able to make tours and to include general popups in the tour (see at the end of their demo), but it seems excessive to me to make a whole new package when it is possible to make this kind of popups with driver.js (even if it's a bit hacky).

I think we could use popper.js or tippy.js to create something custom with which we could have much more flexibility and respond to such queries.

To me, the feature requested in this issue is not to be able to make "standalone" popups but to have a step of the tour that corresponds to the whole page rather than a single element. So I don't think this can be done by mixing driver.js with other libraries, but I'm far from being an expert on that.

federicomarini commented 3 years ago

the feature requested in this issue is not to be able to make "standalone" popups but to have a step of the tour that corresponds to the whole page rather than a single element

I could have provided a screenshot to make it less ambiguous, sorry about that.

What I meant is basically a tour step that basically just is in the middle of the page and is not anchored to any particular UI element - ideally, keeping the rest of the UI shadowed out to put the focus on the mini-popup.

Hope this helps you helping me :wink: