gilbarbara / react-joyride

Create guided tours in your apps
https://react-joyride.com/
MIT License
6.87k stars 527 forks source link

Tour stop when it reaches index 10/step 11 #496

Closed selyon closed 5 years ago

selyon commented 5 years ago

šŸ› Bug Report

I have 20 steps to show, but when it reaches index 10, so step 11 because it starts from zero, the tour is stopped automatically. This is the console log of the object passed to the callback, at index 10 it has lifecycle "init". When it reaches index 10 it print all the other values after that in one second schermata 2019-03-07 alle 17 16 20

This are my steps [ { target: "#guidedTour-step1", content: stringTranslate("tour", "step1"), disableBeacon: true, placement: "center" }, { target: "#guidedTour-step2", disableBeacon: true, content: stringTranslate("tour", "step2"), placement: "right" }, { target: "#guidedTour-step3", disableBeacon: true, content: stringTranslate("tour", "step3"), placement: "right" }, { target: "#guidedTour-step4", disableBeacon: true, content: stringTranslate("tour", "step4"), placement: "right" }, { target: "#guidedTour-step5", disableBeacon: true, content: stringTranslate("tour", "step5"), placement: "right" }, { target: "#guidedTour-step5", disableBeacon: true, content: stringTranslate("tour", "step6"), placement: "right" }, { target: "#guidedTour-step7", disableBeacon: true, content: stringTranslate("tour", "step7"), placement: "bottom" }, { target: "#guidedTour-step7", disableBeacon: true, content: stringTranslate("tour", "step8"), placement: "right" }, { target: "#guidedTour-step9", disableBeacon: true, content: stringTranslate("tour", "step9"), placement: "top" }, { target: "#executionStatus", disableBeacon: true, content: stringTranslate("tour", "step10"), placement: "top" }, { target: "#guidedTour-step11", disableBeacon: true, content: stringTranslate("tour", "step11"), placement: "bottom" }, { target: "#guidedTour-step11", disableBeacon: true, content: stringTranslate("tour", "step12"), placement: "bottom" }, { target: "#guidedTour-step13", disableBeacon: true, content: stringTranslate("tour", "step13"), placement: "left" }, { target: "#guidedTour-step14", disableBeacon: true, content: stringTranslate("tour", "step14"), placement: "right" }, { target: "#guidedTour-step15", disableBeacon: true, content: stringTranslate("tour", "step15"), placement: "right" }, { target: "#guidedTour-step16", disableBeacon: true, content: stringTranslate("tour", "step16"), placement: "right" }, { target: "#guidedTour-step17", disableBeacon: true, content: stringTranslate("tour", "step17"), placement: "right" }, { target: "#guidedTour-step18", disableBeacon: true, content: stringTranslate("tour", "step18"), placement: "right" }, { target: "#guidedTour-step19", disableBeacon: true, content: stringTranslate("tour", "step19"), placement: "right" }, { target: "#guidedTour-step20", disableBeacon: true, content: stringTranslate("tour", "step20"), placement: "right" } ]

Expected behavior

The tour continue as normal

Run npx envinfo --system --binaries --npmPackages react-floater

System: OS: Linux 3.10 CentOS Linux 7 (Core) CPU: (2) x64 Intel(R) Xeon(R) CPU X5650 @ 2.67GHz Memory: 5.64 GB / 15.51 GB Container: Yes Shell: 4.2.46 - /bin/bash Binaries: Node: 11.2.0 - /usr/local/bin/node Yarn: 1.3.2 - /usr/bin/yarn npm: 6.4.1 - /usr/local/bin/npm

selyon commented 5 years ago

This is my callback if it can be usefull

tooltipCallback = data => {
    if (
      data.action === "close" &&
      data.lifecycle === "complete" &&
      data.type === "step:after"
    ) {
      this.setState({ runTour: false });
    }
    if (data.index === 4 && data.type === "step:before") {
      method();
    }
    if (data.index === 5 && data.type === "step:before") {
      anotherMethod();
    }
    if (data.index === 10 && data.type === "step:before") {
      anotherMethod();
      anotherOne();
    }
    if (data.index === 11 && data.type === "step:after") {
      lastMethod();
    }
  };

This is how i use the Joyride component

<Joyride
    run={this.state.runTour}
    steps={steps}
    continuous={true}
    callback={this.tooltipCallback}
/>
selyon commented 5 years ago

I found the problem, Joyride seems to be unable to attach to hidden elements. I have an element, a side panel, that's hidden with display: none. I tried this but it's not working:

if (data.index === 9 && data.type === "step:after") {
      this.props.togglePanel();
    }
saminami commented 5 years ago

Since react state updates are asynchrounous, you might have to wait for the panel to mount. You need to make your tour controlled, and only update stepindex after the state has been updated.

Something like this could work:

`this.props.togglePanel().then(() => { this.setState({ stepIndex: index + (action === ACTIONS.PREV ? -1 : 1) }); })

or a hack: this.props.togglePanel() setTimeout(() => { this.setState({ stepIndex: index + (action === ACTIONS.PREV ? -1 : 1) }); }, 20)

`

check here: https://codesandbox.io/s/github/gilbarbara/react-joyride-demo

selyon commented 5 years ago

I understand this, but my component is already mounted. The div element with the selector is already in the DOM of the page, it's only hidden. I asked why the library can't connect a step to an hidden element and if it's normal this behaviour. If i start the tour from the step that need to show the hidden component, why i can't show it when the event step:before is triggered?

selyon commented 5 years ago

I also tried to stop the code inside the callback, making it "sleep" with a promise and setTimeout, but the tooltip is shown regardless the callback is finished or not. What is the purpose of the callback and the event types if you can't control the flow?

gilbarbara commented 5 years ago

I asked why the library can't connect a step to an hidden element and if it's normal this behaviour.

Because a hidden element doesn't have size and the library needs to position itself with that info. Yes, is the normal behaviour.

I also tried to stop the code inside the callback, making it "sleep" with a promise and setTimeout, but the tooltip is shown regardless the callback is finished or not. What is the purpose of the callback and the event types if you can't control the flow?

Are you using a stepIndex to control the tour? Read more about this in the docs.