Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't go to next step in tour based on element click if page route changes #603

Open
pguduguntla opened this issue Nov 5, 2023 · 5 comments

Comments

@pguduguntla
Copy link

pguduguntla commented Nov 5, 2023

Hey - love the libary!

TDLR: How do I make it so when I click on a link as part of a tour step, the tour continues on the next page without breaking the current tour?


I have a question about a specific use case I have. I want to be able to set up a Tour where a user can click on a link on page-1 (which routes the user to page-2). When the user clicks on this link, I want the tour to advance to the next step on the new page that gets opened.

I have checked out this example with Tours between different routes. However, this only works if the user uses the navigation buttons (next/prev). I want to achieve the exact same effect, but when the user clicks on the actual highlighted element.

I have also checked out this other example where you've set up different tours based on the route of the webpage if a user clicks on a link. However, this doesn't work for my use case because each page has it's own tour and starts from step 0. I want to be able to continue the same tour between pages where the user can click through a link to advance to the next step in the tour.

I have created an example reproduction of the failure case. I am hoping you can give me some pointers on how I can achieve the desired effect.

Here is an video recording how the code fails:
Screen Recording 2023-11-04 at 7 44 51 PM

In this video, the tour works as expected with the navigation buttons, but breaks when nav buttons are disabled and user has to click the element to go to the next page. When the user starts the tour and clicks the "example" link, I want the "/Example page" to open and the tour to advance to the next step and highlight "Subheading".

Ideally, this works for onClick of a link/button, but also other ways that a user interacts with a highlighted element such as typing something into an input box.

@elrumordelaluz
Copy link
Owner

Hi @pguduguntla, thanks for open the Issue and for the detailed explanation.

For these cases, you can control the currentStep when clicking the navigation link, something like:

<NavLink
  data-tour="example"
  to="/Example"
  onClick={() => {
    if (isOpen) setCurrentStep(1);
  }}
  className="nav-link"
>
  Example
</NavLink>

allowing you to be sure that when changing route, the step will be 1 in this case.
Here is a working example.

In this example I also remove the external step state control, which in my opinion is not necessary.
Let me know in any case.

@pguduguntla
Copy link
Author

Thanks for your quick response, @elrumordelaluz ! This was really helpful. Instead of manually defining the onClick listener of the NavLink to advance to the tour, is is possible to pass in the desired action within the steps config itself? I don't want to manually go into each element and add code to the onClick listener.

Something such that I can just define:

steps = [
{
    selector: "[data-tour='example']",
    content: (
      <p>
        This is a <code>paragraph</code> on the page "Home"
      </p>
    )
   action: // add an onClick listener to the element so the tour knows to advance to the next step only when the element is clicked, or in the case of an input, the user types in a specific string
  },
...
]

Is this possible? If so, let me know - would love to see an example of it.

@elrumordelaluz
Copy link
Owner

Is it possible to fire an action as soon as the Tour arrives to the step as described here. However to fire the action you have to land there, while if I understand well, your point is how to arrive to step x when clicking an element external of the Tour. Keep in mind that the Tour doesn't attach events to external elements.

@pguduguntla
Copy link
Author

pguduguntla commented Nov 6, 2023

@elrumordelaluz Got it - that makes sense. I don't need to attach to external elements. I only want to attach the action to the highlighted element.

Using the action property, I just updated your Code Sandbox to have the onClick listener on the steps config rather than the component itself. However, the it seems the tour is not able to attach to the correct element as it did previously.

I've added the following code to do so:

    return steps.map((step, index) => {
      return {
        ...step,
        action: (node) => {
          node?.addEventListener(
            "click",
            function (e) {
              setCurrentStep(1);
            },
            false
          );
        }
      };
    });
  };

  useEffect(() => {
    setSteps(createSteps(steps));
  }, []);

You can check out the full reproduction here: https://codesandbox.io/s/react-tour-router-next-page-when-link-pressed-forked-qt89rw?file=/src/components/Header.js:405-790

Would greatly appreciate if you can help with this :)

@elrumordelaluz
Copy link
Owner

Try queuing the call this way:

const createSteps = () => {
    return steps.map((step, index) => {
      return {
        ...step,
        action: (node) => {
          node?.addEventListener(
            "click",
            function (e) {
              setTimeout(() => setCurrentStep(1), 1);
            },
            false
          );
        }
      };
    });
  };

Here is a working example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants