Code Monkey home page Code Monkey logo

reactour's Introduction

reactour

Tourist Guide and a set of Assistants to travel into your React Components

Documentation

https://docs.react.tours

Packages

The main package, which uses the other ones to highlight parts of your application from an array of steps.

A customizable Component to highlight certain element or area of the viewport.

A customizable Component to attach to an element or position of the viewport to show content.

A set of helper functions used by the other packages.

The place where all the stuff is visible working, live here.

Sponsored by

Gold sponsors 🥇

Frigade sponsor

Reactour is proud to be sponsored by Frigade, a developer tool for building better product onboarding: guided tours, getting started checklists, announcements, and more.

Repo Activity

Alt

License

MIT © Lionel Tzatzkin

reactour's People

Contributors

ahmedbera avatar andreasrobert avatar andzav avatar belgac avatar budda avatar cairnswm avatar dependabot[bot] avatar elrumordelaluz avatar flak15 avatar gdsrosa avatar iamdey avatar kazuyoshi-yamada-wmj avatar klepas avatar matsumos avatar mepajanitza avatar miko007 avatar nelsonwong1012 avatar nerdysoft-dev avatar nervetattoo avatar qboot avatar rileyjshaw avatar slivmi avatar sorokin-vladimir avatar tarqu1n avatar uig-julia avatar utkarsh-dixit avatar wahur666 avatar yaodingyd avatar yossijacob avatar zackharley avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

reactour's Issues

new feature

Hi,
i just discover your library and it's Awesome.
One thing that is missing is the option to change steps from other components, from outside the content (goto).
A lot of the onboarding libraries today suggest that option.
Tnx.

[Bugfix/Improvement] Step observers break everything in test env

Current behavior:

  • TourPortal tries to access MutationObserver in all envs, which throws a ReferenceError: MutationObserver is not defined in test.

Expected/desired behavior:

  • Should only access the MutationObserver API if it's available (i.e. we're in a browser). Users of the component could do this for every defined step and/or tour (we're currently doing observe: global.MutationObserver ? '#elementSelector' : null,), but it seems much simpler if the component only accesses APIs that are available.

SyntaxError: import declarations may only appear at top level of a module

Hi 😃

I tried to use this module but I always get this error 😄 :
SyntaxError: import declarations may only appear at top level of a module

I looked in the module files and yes the imports are never at the top of file 🤔 So I put all the imports in every file at the top and it's still not working, any idea ? 😃

Thanks in advance,
lucienbl

Possible to have multiple Tours within one application ?

Hi,

So in my scenario I am trying to have a tour per page if you will.
I was attempting to do this by creating a separate Tour component and passing steps to it as props when I triggered it to display depending on what page was showing. I get the following error:

TourPortal.js:415 Uncaught TypeError: Cannot read property 'style' of undefined
at TourPortal.render (TourPortal.js:415)

It seems to me that if tour 1 has 3 steps and tour 2 only 2 then this occurs so it seems the steps array size is the issue even though I can see the steps being passed to the Tour as I am creating it the second time.

Any help greatly appreciated

thanks,
alx

Possible to trigger actions between steps ?

Hello,

I have an application which switches views,
I would like a tour which walks through all views.
For this I am triggering view changes using step actions.
However the issue is that the selectors are not ready until after the action has run by which time the step is showing but cannot anchor to the selector.

So is there a way to do what I am trying to do already ?
If not perhaps a feature request would be to allow actions to run between steps somehow

thanks,
alx

Great library! Mask Question and General Feedback

Thanks so much for making this great library! I’m using it with Redux for a product tour of a canvas-based application. Things generally worked great out of the box.

Regarding the mask, is there a proper way to turn it off?

For my tour, the user needs to interact with the page while the tour goes on. I re-enabled scrolling by removing the default from the onAfterOpen property, and I disabled the mask by setting maskClassName to:

.tourMaskStyle {
  position: absolute;
  z-index: -100;
  background-color: transparent;
}

No worries if not — such a maskOn prop could be a good future addition.

If you're open to it, some general feedback:

  • I love the action property in each step as I’m able to pass in Redux actions that set-up aspects of the tour for the user.

  • Everything flows really nicely and smoothly on interaction with the tour box - impressively done!

  • Adding some more properties at the step-level might be useful such as being able to offset the step in a certain x, y, direction vs. globally for all steps. In my case, I tried to position the tour box in a specific spot (partially over the large canvas element) so the user would be able to see the display better. I initially intended to limit the user's interaction to that of the bounding box, but the approach wasn't flexible enough for my needs given how the step and canvas were being displayed. I didn't find a great solution with the offset property so I ended up disabling the mask and re-enabling the scroll, which actually ended up working really nicely.

  • Could you explain how inViewThreshold would be used and/or give an example? I played with it but didn’t see any results by changing the threshold.

  • Consider clarifying the word ‘helper’ for className prop documentation. It seems to be the Tour Guide pop-up box after experimenting with it.

  • scrollDuration units are in milliseconds?

  • Consider adding some more keywords to your npm package so it’s easier to be found. I tried out several other libraries before coming across reactour. I liked your work the best! Some additional keywords could include: onboarding, on-boarding, walkthrough, walkthru, product-tour, redux, joyride, hopscotch, and shepard.

Hopefully, the above can be useful --- thanks for all your hard work on this library!
Bryant

Replace the next button with renderNextButton func.

Right now, we can customize the button text with nextButton prop. However, if we want to replace our own button, such as material-ui, we can not put the button into that prop since we are nesting a <button /> into another <button />, It will be much better if we can add a hoc to give the ability to the user so that we can customize everything of the button and the close button.

Only pass childList to MutationObserver Config

Summary

Within the MutationObserver Handler you only deal with childList mutations. You even filter everything else out. See following Ref:

reactour/src/TourPortal.js

Lines 182 to 204 in 000bf20

mutations.forEach(mutation => {
if (
mutation.type === 'childList' &&
mutation.addedNodes.length > 0
) {
const cb = () => stepCallback(mutation.addedNodes[0])
setTimeout(
() =>
this.calculateNode(
mutation.addedNodes[0],
step.position,
cb
),
100
)
} else if (
mutation.type === 'childList' &&
mutation.removedNodes.length > 0
) {
const cb = () => stepCallback(node)
this.calculateNode(node, step.position, cb)
}
})

Solution

I would suggest to set the MutationObserver Config to:

{ childList: true }

isOpen not changing

Great library and looks awesome. but the onRequestClose function is successfully changing the state of IsTourOpen, but the Tour component is not updating it's props isOpen. Any thoughts on this? Really wanted this to work but ...

restart tour

Hi man, i was wondering if theirs a clean way to restart the tour when the user finish all the steps?
In our case, we have a button that the user can always come back to the tour and as you know it's start from the step that the user quit and thats fine but, when he got to the final step and he finish or quit, if want to run the tour again, he start from the final step and that's kind of radicals so, what we want is after the last step, restart the tour to the first step.

I used the startAt params and it's working but i got a warning from react (###

forceUpdate(...): Cannot update during an existing state transition (such as within render...

)
and i kind a think that's a nasty solution.

my code:

resetTour = () => {
       let {tourStore} = this.props;
       return tourStore.currentStep === this.steps.length ? 0 : undefined
};

<Tour startAt={this.resetTour()}

Set disabled state for first/last buttons when contextually unavailable

Hi there,

Thanks for writing this component! :-)

I have a small accessibility/UX improvement suggestion—

It would be nice to have the left/right arrow next/previous buttons ideally set to disabled when either on the first or last steps respectively (viz., where there is nothing to go back to, or nothing to go next to).

Rationale:

  • As a user, I should be informed when a button’s actions are currently unavailable.
  • As a developer/implementer, it would be nice to be able to target the disabled buttons for further UX/stylistic improvements (eg cursor: not-allowed for button:disabled { … }).

I have a few other accessibility suggestions in mind. I’d be happy to make additional issues and assist in closing them, if you’re interested.

Dependency Issue with latest release - 1.8.6

Hi reacttour people, our npm builds have been breaking and it looks like the latest version of your package is having dependency issues. We are getting the following error on build:

Module not found: Error: Can't resolve 'styled-components' in '/home/jenkins/workspace/{project}/node_modules/reactour/dist/components'

If this is just me being ignorant I apologize but it looks like rolling back to 1.8.5 resolved the problem before you removed the dependency.

Document for observe

Hi.
I have tour with two step.
one button if user onClick will open a modal and forcus to element in modal.
I saw example have observe. i'm try config steps but not working.

   <Tour type="abc" isOpen={this.state.showTours}
           onRequestClose={() => this.setState({ showTours: false })}
           steps={[
                 {
                            selector: '.add-widget',
                            'content': 'ahihi',
                        },
                        {
                            selector: '.add-widget',
                            'content': 'ahihi',
                            observe: '.new-widget'
                        },

                    ]} />

Can you write an example of this problem?

Hide Close button on every step

I think this is not possible right now, so I guess this is a feature request.

It would be really helpful to include a property to hide the Close button, so we can fully manage the tour open state, and prevent the user from skipping steps if necessary.

Safari scroll issue

When scrolling the page content scrolls but the tour popup and mask stay in the same spot of the window.

Safari: Version 10.1.1 (12603.2.4)
MacOS: 10.12.5 (16F73)

Awesome project! Love tours :)

More documentation on the observer functionality

Hi there,

fantastic module! Great job.

I'm trying to figure out how you get the observer working, like in the last example of the demo. I have a similar use case where I'm highlighting a button but I want to change the focus to a drawer that gets displayed if the user clicks the button.

I tried adding a selector for the drawer in the 'observer' property but this doesn't seem to do anything. Some clarification on the feature would be grand :)

Not scrolling elements into view

reactour is not auto-scrolling to elements outside the viewport. My header and sidebar are fixed elements, and the main element contains the components, including those not being scrolled to.

screen recording 2018-01-22 at 04 25 pm

My app has the following markup:

<div class="app">
  <header class="app-header"></header> <!-- fixed el -->
  <div class="app-body">
    <div class="sidebar"></div> <!-- fixed el -->
    <main></main>
  </div>
</div>

Any idea what could be preventing the scrolling?

Improve button semantics by adding ARIA labels

Hi again,

Currently the <button> navigation elements just hold SVGs.

It would be nice to improve the semantics and accessibility of the buttons by giving each one an aria-label.

Technically, this is quite straight-forward to do, with the only complication being localization/internationalization to remain language agnostic. To that end it would probably be nice to expose the ARIA label text via a prop to implementers? :-)

startAt does not work as expected

If you pass both isOpen true and startAt as the same time you are going to get the tour to open on the previous startAt instead of the one passed in startAt.

I think it is because the open method is called in componentWillReceiveProps. it then get startAt from current props which is not updated yet with the new values. it should get it from the nextProps.

this.open()

So this line will always get the startAt from the current props before the update

const { onAfterOpen, startAt } = this.props

I am not sure but maybe having the open method get the props as a parameter can solve this.

Allow passing children to show them above the mask

Hello
I'm trying to make my own controls located at bottom of page in a fixed position. But since Reactour adds a mask at the end of DOM it's impossible to make this.

Proposed usage

<Tour {tourProps}>
  <button onClick={doSemething}>Next</button>
</Tour>

and it would render something like this

<div class="reactour-portal">
  <div>
    <div class="reactour__mask">...</div>
    <div class="reactour__helper">...</div>
    <div class="reactour__children">
      <button>Next</button>
    </div>
  </div>
</div>

Step update from outside component

Hey! Congrats on building a great library! I'm trying to work out if it's possible to update the step number from outside the component ie. change from step 1 to step 2 via a button that is outside of reactour. Is the update prop for this purpose? Thanks.

func this.setState() error loop

Hi,
I use

<Tour
        steps={steps}
        isOpen={this.state.isTourOpen}
        onRequestClose={this.closeTour} 
        getCurrentStep={()=>this.setState({test:false})}
/>

or


{
    selector: '[data-tut="reactour__logo"]',
    content: `And this is our cool bus...`,
   action:()=>{ this.setState({test:false}) }
  },

In this.setState({test:false}) code , will report an error in the loop..

help me~~~

Centering the Nav Arrow and Dots

Hello -- Is there a trick to centering the navigation arrows and dots into the middle of the tour guide helper? They are currently left aligned, which looks awkward if there are not a large number of steps in the tour.

In Chrome's inspector, the following does the trick:

margin-left: 0;
margin-right: 0;
justify-content: 'center';

I don't seem to be able to pass this through the className prop to impact the div.

Any suggestions/help would be great!

Using reactour in an application that also uses styled-components destroys styles

Setup

Create a project that already uses styled-components. Add reactour as a dependency. You will see that it destroys the styles.

Example

Look at this CodeSandbox (https://codesandbox.io/s/lpwj1n5697)

Suggestions

Styled Components version >=3.2.5 offers a constant SC_ATTR that can be set during the build. It allows some kind of namespacing of the styled component. But you currently do not bundle the styled-components library into your bundle. This needs to be changed than.

Turning off the SVG mask

Hello -- The tour that I've constructed requires that users interact with content on the screen during the tour (e.g. canvas) so I need to turn off the mask entirely.

I upgraded to 1.7.1 from 1.6.2. Previously, I used maskClassName with the following to turn off the mask:

.tourMaskStyle {
  display: none;
}

In 1.7.1, maskClassName no longer appears to work. The class appears to get passed into SvgMask as a prop className={maskClassName}, but then this className prop is not actually used in the SvgMask file.

Is there a new way to turn off the mask? Advice on how to proceed would be appreciated! Thanks!

goToStep prop does not work when changing the value on closed tour

Hey,

I'm using your library, but we have a bit non-standard use case in our app. Some tour steps are not available at first, so I'm generating an array with steps dynamically, based on Redux app state. This works totally fine. The problem occurs when the user has e.g. finished the tour (so he's currently on the last step, say, stepId = 10) and the app goes back to the state in which there are only 7 steps. I would expect that something like this would do the trick:

componentDidUpdate() {
    if (!this.props.tabIsActive && this.props.currentStep > 6) {
      this.props.setStep(6);
    }
  }

  render() {
    return (
      <Tour
        steps={this.getSteps()}
        isOpen={this.props.isTourOpen}
        onRequestClose={this.props.toggleTour}
        getCurrentStep={this.props.setStep}
        goToStep={this.props.currentStep}
      />
    );
  }

but it doesn't work - the tour is still stuck somewhere on that non-existing step and throws this:

app:8 Uncaught TypeError: Cannot read property 'style' of undefined
    at ProxyComponent.render (TourPortal.js:451)
    at ProxyComponent.hotComponentRender (react-hot-loader.development.js:620)
    at ProxyComponent.proxiedRender (react-hot-loader.development.js:635)
    at finishClassComponent (react-dom.development.js:13194)
    at updateClassComponent (react-dom.development.js:13156)
    at beginWork (react-dom.development.js:13825)
    at performUnitOfWork (react-dom.development.js:15864)
    at workLoop (react-dom.development.js:15903)
    at HTMLUnknownElement.callCallback (react-dom.development.js:100)
    at HTMLUnknownElement.nrWrapper (app:8)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:138)
    at invokeGuardedCallback (react-dom.development.js:187)
    at replayUnitOfWork (react-dom.development.js:15311)
    at renderRoot (react-dom.development.js:15963)
    at performWorkOnRoot (react-dom.development.js:16561)
    at performWork (react-dom.development.js:16483)
    at performSyncWork (react-dom.development.js:16455)
    at interactiveUpdates$1 (react-dom.development.js:16720)
    at interactiveUpdates (react-dom.development.js:2150)
    at dispatchInteractiveEvent (react-dom.development.js:4533)
    at HTMLDocument.nrWrapper (app:8)

The above error occurred in the <TourPortal> component:
    in TourPortal

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://fb.me/react-error-boundaries to learn more about error boundaries.

I found an absolutely disgusting workaround, but I wish I wouldn't have to do that:

componentDidUpdate() {
    if (!this.props.tabIsActive && this.props.currentStep > 6) {
      this.props.setStep(6); // this is actually not needed anymore
      this.tourRef.portal.state.current = 6; // this is ref from Tour component
    }
  }

Please make it work as one would expect if possible. Thanks.

Modal Background color change

I wanna change modal background color to white background color,Like background-color: rgba(1,1,1,.7) to background-color: rgba(1,1,1,-0.03).
Please help me asap,Thank you

Skip the step if the node is not found

New feature request!!
We have some divs which are rendered only sometimes. We want to show the tour step for those if they are being displayed. If they are not being rendered just move to the next step.

[IE] css variables are not supported in internet explorer

Hey,
thanks for your amazing component!
Everything works perfectly fine (even on IE), but I noticed that when I set --reactour-accent to different color it is not working in IE. I'm talking about this line:

background-color: var(--reactour-accent);

Googled that css variables are not supported in IE:
https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables
Is there any other way to change the color?

Improve Observer

At the moment, the MutationObserver observes elements that appears in the DOM. Could be useful to observe also css changes, like display, opacity used to show/hide UI elements.

Scroll for elements that are loaded after the tour has started.

Hi,
I'm implementing Reactour on my platform but Im having issues with scrolling to the next step. I'm building a tour that shows the user how to include his/her agenda on the platform. The problem is that as he/she starts the tour and selects the option to add an agenda, a form opens on the page so the user can fill out their information, react tour finds the selectors but doesn't scroll the page. I followed the sandbox implementation and got the tour to work but not the scrolling.

License?

Is this project MIT licensed?

Idea: Replace Observer with something like AutoSkip

Summary

As far as I understood, the actual intention of the observer function is to let the display move to a new object.
I think it mostly makes sense for the user to also provide new content in the Tour-Card after the change.

Example Step

[
  {
    selector: '[data-tour="my-first-step"]',
    content: 'First Step',
    position: 'top',
    autoSkip: true
  },
 {
    selector: '#nextStep',
    content: 'First Step',
    position: 'top',
  },
]

If autoSkip set to true, go to next step when a node '#nextStep' appears in the DOM.

TourPortal crashes the app after being unmounted while open

Scenario

  • Use Tour by conditionally rendering it rather than using isOpen. I.e. switch between rendering it with isOpen={true} and not rendering it at all. (Rationale: This is the default way to use React components, so it should be supported.)
  • Open the tour and close it.
  • Remove one of the elements highlighted by the tour from the DOM.

Expected

It works :)

Actual

App crashes with TypeError: Can't get 'getBoundingClientRect' of undefined. or some such.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.