Giter VIP home page Giter VIP logo

stackbuilders / react-native-spotlight-tour Goto Github PK

View Code? Open in Web Editor NEW
165.0 24.0 24.0 28.88 MB

A highly customizable tour feature with an awesome spotlight effect

Home Page: https://stackbuilders.github.io/react-native-spotlight-tour/

License: MIT License

TypeScript 86.62% JavaScript 2.47% Ruby 2.92% Objective-C 3.07% Objective-C++ 1.08% HTML 0.38% Kotlin 3.45%
react-native tour spotlight hacktoberfest customizable android ios step-by-step user-guide app-tour

react-native-spotlight-tour's Introduction

React Native Spotlight Tour

All Contributors

CI Release NPM version NPM downloads NPM license GitHub Release Date Known Vulnerabilities

react-native-spotlight-tour is a simple and intuitive library for React Native (Android, iOS, and Web compatible). It uses Floating UI under the hood in order to handle elements positioning, it re-exports all floating-ui middlewares to be configured in the tour. It also allows you to implement a highly customizable tour feature with an awesome spotlight effect. This library handles animations at the native level and is perfect for the following:

  • Guiding users on how to use your application
  • Showing an introduction to your users

spotlight-bounce-gif spotlight-fade-gif spotlight-slide-gif spotlight-rect-gif

Requirements

Install

With npm:

npm install react-native-spotlight-tour

With yarn:

yarn add react-native-spotlight-tour

🚨 Breaking changes: v2 to v3

This major update brings a few fixes, some great new features, and some breaking changes. These are some highlight you'll need to consider while upgrading from v2 to v3:

  • The package has been renamed from @stackbuilders/react-native-spotlight-tour to just react-native-spotlight-tour
    • Don't worry, this library is still developed and maintained by the Stack Builders Inc. team!
    • Remove the former package from your dependencies and use the command described in the Install section
    • Rename any import from the previous name to use just react-native-spotlight-tour instead
  • Tooltip positioning was refactored
    • Props related to the tooltip position were removed from SpotlightTourProvider and the TourStep object.
      • Both Align and Position enums were removed
      • Both alignTo and position props were removed
    • We now delegate the positioning to FloatingUI, so you can use the floatingProps prop to configure its global behavior or granularly on each step.
    • Middleware functions are re-exported from @floating-ui/react-native to react-native-spotlight-tour.
    • You may not need to do changes on floatingProps since the default behavior is very similar to v2

Usage

To be able to use the tour, you'll need to wrap everything around a SpotlightTourProvider. This provider component will also give you access to a hook to retrieve the SpotlightTour context, which gives information and fine control over the tour.

import { Button, Text, View } from "react-native";
import {
  AttachStep,
  SpotlightTourProvider,
  TourStep,
  flip,
  offset,
  shift,
} from "react-native-spotlight-tour";

const mySteps: TourStep[] = [
  // ...setup the steps
];

return (
  <SpotlightTourProvider
    steps={mySteps}
    overlayColor={"gray"}
    overlayOpacity={0.36}
    // This configurations will apply to all steps
    floatingProps={{
      middleware:[offset(5), shift(), flip()],
      placement: "bottom",
    }}
  >
    {({ start }) => (
      <>
        <Button title="Start" onPress={start} />

        <View>
          <AttachStep index={0}>
            <Text>Introduction</Text>
          </AttachStep>

          <Text>
            This is an example using the spotlight-tour library.
            Press the Start button to see it in action.
          </Text>
        </View>

        <View>
          <AttachStep index={1}>
            <Text>Documentation</Text>
          </AttachStep>
          <DescriptionText>
            Please, read the documentation before installing.
          </DescriptionText>
        </View>
      </>
    )};
  </SpotlightTourProvider>
);

Floating-UI props can be defined in the <SpotlightTourProvider/> and this will be applied to all tour steps. If no configuration is given it will take a default with the next values: middlewares: [flip(), offset(4), shift()] and placement: "bottom".

The tour requires an array of steps to be configured, which will map directly to each <AttachStep /> index. Bellow is a complete example of a TourStep array:

import { Button, Text, View } from "react-native";
import {
  Align,
  TourStep,
  useSpotlightTour
} from "react-native-spotlight-tour";

const mySteps: TourStep[] = [{
  // This configurations will apply just for this step
  floatingProps:{
    middleware: [offset(0), shift(), flip()],
    placement: "right",
  },
  render: ({ next }) => (
    <View>
      <Text>This is the first step of tour!</Text>
      <Button title="Next" onPress={next} />
    </View>
  )
}, {
  before: () => {
    return DataService.fetchData()
      .then(setData);
  },
  render: () => {
    // You can also use the hook inside the step component!
    const { previous, stop } = useSpotlightTour();

    return (
      <View>
        <Text>This is the first step of tour!</Text>
        <Button title="Previous" onPress={previous} />
        <Button title="Stop" onPress={stop} />
      </View>
    );
  }
}];

Floating-UI props can be defined in each step for a custom configuration. If no floating configuration is specified in the step it will take the one defined in the <SpotlightTourProvider/>.

You can also find a complete example here.

Built-in Helper Components

You can take advantage of the built-in customizable components. For example, our TourBox component can be used as a tooltip container for each step.

import { Text } from "react-native";
import { Align, TourBox, TourStep } from "react-native-spotlight-tour";

const tourSteps: TourStep[] = [{
    render: props => (
      <TourBox
        title="Tour: Customization"
        titleStyle={{
          fontFamily: 'Roboto',
          color: '#90EE90',
          fontWeight: 'bold'
        }}
        backText="Previous"
        nextText="Next"
        {...props}
      >
        <Text>
          {"This is the third step of tour example.\n"}
          {"If you want to go to the next step, please press "}<BoldText>{"Next.\n"}</BoldText>
          {"If you want to go to the previous step, press "}<BoldText>{"Previous.\n"}</BoldText>
        </Text>
      </TourBox>
    ),
  }];

Tour customization

The SpotlightTourProvider also allows you to customize the overlay through the overlayColor and overlayOpacity props.

import { AttachStep, SpotlightTourProvider, TourStep } from "react-native-spotlight-tour";

const mySteps: TourStep[] = [
  // ...
];

return (
  <SpotlightTourProvider steps={mySteps} overlayColor={"gray"} overlayOpacity={0.36}>
    {({ start }) => (
      <>
      {/* ... */}
      </>
    )};
  </SpotlightTourProvider>
);

Besides above customizations, you can also define the transition animation see motion and the behavior when the user presses the backdrop see onBackdropPress. Otherwise if you wish to make them different for an specific step you could override this properties in the TourStep configuration.

import { Button, Text, View } from "react-native";
import {
  Align
  AttachStep,
  SpotlightTourProvider,
  TourStep,
  TourBox
} from "react-native-spotlight-tour";

const tourSteps: TourStep[] = [{
    motion: "fade",
    onBackdropPress: "stop",
    render: props => (
      <TourBox
        title="Tour: Customization"
        backText="Previous"
        nextText="Next"
        {...props}
      >
        <Text>
          {"This is the first step of tour example.\n"}
          {"If you want to go to the next step, please press "}<BoldText>{"Next.\n"}</BoldText>
          {"If you want to go to the previous step, press "}<BoldText>{"Previous.\n"}</BoldText>
        </Text>
      </TourBox>
    ),
  }];

return (
  <SpotlightTourProvider
    steps={tourSteps}
    overlayColor={"gray"}
    overlayOpacity={0.36}
    onBackdropPress="continue"
    motion="bounce"
  >
    {({ start }) => (
      <>
      <Button title="Start" onPress={start} />

       <View>
          <AttachStep index={0}>
            <Text>Introduction</Text>
          </AttachStep>

          <Text>
            This is an example using the spotlight-tour library.
            Press the Start button to see it in action.
          </Text>
        </View>
      </>
    )};
  </SpotlightTourProvider>
);

API Reference

To view all the types, options, and props, please check the complete API Reference documentation.

Contributing

Do you want to contribute to this project? Please take a look at our contributing guideline to know how you can help us build it.


Stack Builders Check out our libraries | Join our team

Contributors ✨

Thanks goes to these wonderful people (emoji key):

Jose Luis Leon
Jose Luis Leon

💻 ⚠️ 📖 🚇 🚧 👀
Sebastián Estrella
Sebastián Estrella

🚇
Angie Rojas
Angie Rojas

💻 📖
Fernanda Andrade
Fernanda Andrade

🚇 ⚠️
Steven Cuasqui
Steven Cuasqui

📖
Alexander Mejía
Alexander Mejía

💻
Carolina López
Carolina López

💻 💡
cmarcag
cmarcag

⚠️
Ricardo Arrobo
Ricardo Arrobo

💻 📖
Mohammad Abkal
Mohammad Abkal

📖
Alexander Pokhil
Alexander Pokhil

💻
Alejandro Vivanco
Alejandro Vivanco

💻 👀
Wellington Mendoza
Wellington Mendoza

👀
Christian Samaniego
Christian Samaniego

👀
beKool.sh
beKool.sh

📖
Add your contributions

This project follows the all-contributors specification. Contributions of any kind welcome!

License

MIT, see the LICENSE file.

react-native-spotlight-tour's People

Contributors

alejo0o avatar alex0jk avatar allcontributors[bot] avatar bekoool avatar christianmarca avatar dependabot[bot] avatar flandrade avatar franzgb avatar joselion avatar krarrobo1 avatar lopenchi avatar rojastob avatar sestrella avatar stevencuasqui 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  avatar

react-native-spotlight-tour's Issues

Android Layout Problem with 2.0

The 2.0 Version runs fine on iOS. But on Android i encountered a weird behavior.

1 - 2 Seconds after the spot animation is finished, the TourStep View jumps to the top of the screen and then back to its right position. Very fast but visible. It happens on every transition (next/previous). If you stay on the step it does not jump again.

I disabled/enabled the native driver, no change.

The 1.0.2 version does not have this error.

"react-native": "0.68.5"
"react-native-svg": "^12.4.0"

Add continuous integration (CI)

We would like to have a continuous integration tool so compilation, linting, and tests can be checked on every Pull Request. a good candidate will be CircleCI as we already have an organization account there. We must also be sure to add the integration with GitHub with the checks required on protected branches like master.

Question: How to display arrow

I created a ref and added it into floatingProps middleware but the arrow didn't display.
Here is my code:
const arrowRef = useRef(null);
...
floatingProps={{
middleware: [
offset(4),
shift({
padding: 10,
}),
flip(),
arrow({ element: arrowRef }),
],
placement: 'bottom',
}}
...

Use WebPack to build and serve the Web version of the example

In the example app, we support React Native Web using the Metro bundler with the metro.config.web.js configuration to create a bundled JS file to consume it from the index.html. This is not ideal for two reasons:

  1. We are only creating a bundle that can be used directly at production, so we don't have a way to handle everything related to web development (assets, code splitting, CSS/styling, etc.).
  2. We don't have a real development server, we just use a static server to serve the bundled JS on the index.html

Known issues

The main reason we started with a static server was that the example project is a workspace on a mono repo, so we need to find a way to consume react-native-spotlight-tour from another workspace and be able to replace all references to react-native imports with react-native-web. For iOS and Android, we use rnx-kit to solve this problem. But the web structure is different and rnx-kit doesn't seem to work as expected.

Improve naming and exposure of the library

As the library came from a different project, we would like to improve some names to something that makes more sense to the current library name.
Also, the library currently exposes all its context on the useTour() hook. We would like to limit the exposure only to properties and functions relevant to the usage of the library

Add tests to the library

This library came from another project and the tests it used to have were highly coupled to that specific project. We'd like to add test to the library taking into account the following points:

  • Integration tests might be challenging since we're declaring the core libraries as peer dependencies (react, react-native, react-native-svg), so they will not be actually installed
  • One of the core features of the library relies on measuring the layout of components across the screen. However, this is not possible in the context of an integration test because the components are never actually rendered, therefore measurements will always be undefined

Crash on Android (Expo 47): "attempt to invoke virtual method 'double java.lang.Double.doubleValue()' on a null object reference"

This happened after I upgraded my app to Expo 47. The library was working on SDK 46.

As soon as I start the tour, the app crashes. It only happens on Android, iOS and web still work. This is the error message I get:

Screenshot_20230105-155559

Here's my package.json:

  "dependencies": {
    "@expo-google-fonts/roboto": "0.2.2",
    "@expo/webpack-config": "0.17.3",
    "@react-native-async-storage/async-storage": "1.17.11",
    "@react-native-firebase/analytics": "14.11.0",
    "@react-native-firebase/app": "14.11.0",
    "@react-native-firebase/crashlytics": "14.11.0",
    "@react-navigation/native": "6.0.11",
    "@react-navigation/native-stack": "6.7.0",
    "@react-navigation/stack": "6.0.11",
    "@stackbuilders/react-native-spotlight-tour": "2.0.0",
    "apisauce": "2.1.5",
    "axios": "1.2.2",
    "bson-objectid": "2.0.3",
    "compression": "1.7.4",
    "dayjs": "1.11.4",
    "expo": "47.0.11",
    "expo-app-loading": "2.1.1",
    "expo-apple-authentication": "5.0.1",
    "expo-auth-session": "3.8.0",
    "expo-av": "13.0.2",
    "expo-dev-client": "2.0.1",
    "expo-device": "5.0.0",
    "expo-font": "11.0.1",
    "expo-notifications": "0.17.0",
    "expo-random": "13.0.0",
    "expo-splash-screen": "0.17.5",
    "expo-status-bar": "1.4.2",
    "expo-updates": "0.15.6",
    "expo-web-browser": "12.0.0",
    "express": "4.18.1",
    "firebase": "9.9.2",
    "lodash": "4.17.21",
    "mobx": "6.7.0",
    "mobx-persist-store": "1.0.6",
    "mobx-react-lite": "3.4.0",
    "native-base": "3.4.22",
    "numeral": "2.0.6",
    "react": "18.1.0",
    "react-apple-login": "1.1.6",
    "react-dom": "18.1.0",
    "react-hook-form": "7.33.1",
    "react-native": "0.70.5",
    "react-native-circular-progress": "1.3.7",
    "react-native-gesture-handler": "2.8.0",
    "react-native-keyboard-aware-scroll-view": "0.9.5",
    "react-native-keychain": "6.2.0",
    "react-native-modal": "13.0.1",
    "react-native-pager-view": "6.0.1",
    "react-native-purchases": "5.0.2",
    "react-native-reanimated": "2.12.0",
    "react-native-safe-area-context": "4.4.1",
    "react-native-screens": "3.18.2",
    "react-native-svg": "13.4.0",
    "react-native-swiper-flatlist": "3.0.17",
    "react-native-tab-view": "3.3.0",
    "react-native-toast-message": "2.1.5",
    "react-native-web": "0.18.10",
    "react-native-web-webview": "1.0.2",
    "react-native-webview": "11.23.1",
    "react-native-youtube-iframe": "2.2.2",
    "react-youtube": "9.0.3",
    "semver": "7.3.7",
    "supermemo": "2.0.17"
  }

React is not defined

Hello!
I'm facing this issue, I'm using the library for the first time:
Screenshot_1692808807
Actually before this issue I had similar errors which disappeared by adding
import React from "react"
to these files:
node_modules/@stackbuilders/react-native-spotlight-tour/src/lib/SpotlightTour.provider.tsx
node_modules/@stackbuilders/react-native-spotlight-tour/src/lib/components/attach-step/AttachStep.component.tsx
node_modules/@stackbuilders/react-native-spotlight-tour/src/lib/components/tour-overlay/TourOverlay.component.tsx
But now I'm blocked. What is happening? Thanks!

Prepare actions for the stop event by using onStop property

Add the possibility to run some events or actions after the tour stops by adding a new prop to the SpotLightTourProvider called onStop. This callback receives the current step index as an argument in order to know in which step the tour stopped.

Add an optional default rendered component for each step

When this feature was first introduced in Amira there was a component collect TourBox that served as a default layout for content that will be rendered in each step of the tour. It was used some way like this:

<TourBox {...RenderProps}  title="This is a header title">
  {contents}
</TourBox

The Tour Box included elements like a header and buttons to go forward or backwards in the steps.
I noticed that something like this is not in this library. While I understand that this is due to the fact that we want to have the most customizable implementation. I think that having a default element to render in each step will help with using the library and understanding it better.

Something I think that instead of having a component called tour box that the user can use, we could add some properties to the TourStep interface for customizing different elements of a default "TourBox" like the styles of the next and back button, style of the title and the contents inside the TourBox and also have a property for the user to have it's own component rendered in each step as we have right now.

This could work like the props in this library: https://github.com/Jacse/react-native-app-intro-slider

Jump Tour Steps

Suppose if I wish to jump tour steps on condition. For example if a condition is satisfied it moves from index 0 to 3 else it moves from index 0 to 1. Is this possible?

Tutorial Content is not align correctly. [bug]

Hello,

I am using this component to implement product guide. It's working as well at first time.
But sometimes content is not align correct on iPhone 12, 13 devices.

It's working as well at iPhone X devices.

IMG_5316.MP4

This is my code.

const profileSteps = [
{
alignTo: Align.SCREEN,
position: Position.BOTTOM,
before() {
return new Promise(resolve => {
scrollViewRef.scrollTo({y: 0, animated: true});
resolve();
});
},
render: ({ next }) => (
<GuideCard
description={i18n.t("guides.profile.title")}
onNext={next}
/>
)
},
{
alignTo: Align.SCREEN,
position: Position.TOP,
before() {
return new Promise(resolve => {
scrollViewRef.scrollToEnd({animated: true});
resolve();
});
},
render: ({ previous, stop }) => (
<GuideCard
description={i18n.t("guides.profile.delete_account")}
onPrev={previous}
onStop={() => {
stop();
Storage.PROFILE_TUTORIAL.set('true');
}}
/>
)
},
];

Add example of the project

It's very common in this kind of libraries to have an example project available in the repository, so users can have a better understanding of how to implement the library. This example project will also help developers to easily test new features, improvements, bug fixes, etc. Finally, using this example project we can easily create a GIF image that can be added to the project's README.md to give a good idea of what the library looks like.

Note: The example project should be excluded from distribution using the .npmignore file

Possible performance issues on Android

After testing the library around I noticed that there is a possibility for a transition of being slow or laggy. This is an issue mostly in old android phones, but newer ones could present the issue to a lesser degree.

I wonder, what could be done to improve the performance of the animations.

Add README.md to the example

We should add a README.md to the example with instructions on how to run the example locally. Specifically, we need to describe that the library should be packed first with yarn pack and then we can do cd example/ and yarn install. Adding some extra instruction on about installing the app with yarn android or yarn ios would be nice too 🙂

Add CircleCI to the project

Now we have tests on the project, we need to run all check on a continuous integration environment. CircleCI is a great option since we already have some other projects there. The CI should be in charge of:

  • Running static checks (TS compile, linter)
  • Build the project
  • Run tests
  • Release new versions when merged to the release branch
    • Nice to have: Commit and push a version tag after each release

Suggestion: Add ability to hide/show the Tour

Hello 👋

I would love to have the ability to hide the tour temporarily and then show it again.
I want the user to be able to perform some actions in between the steps.

I can mimic this behavior by saving the last non-undefined current, calling stop(), and then calling goTo(lastCurrent). However, it's far from ideal, as it has the setSpot(ZERO_SPOT) on the stop() method it performs some animations (at least in slide).

The context could provide a simple hide() and show() that is managed by the library itself, making it easier to use and with better (or no) transitions. Also, calling next()/previous() could still work anyway :)

Warpping functional components in AttachStep doesn't seem to work

Internally, AttachStep clones the child and attaches a ref to it so it can use measureInWindow when ever the layout changes. This seems to not work if the child component is a functional component as I got this error:

Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

Support for tour steps that have no spot (no AttachStep)

I haven't found anything in the examples or guides showing how one would include a tour step that does not have an associated AttachStep - ie. a step where the spotlight goes away and the rendered tooltip is just centered. Am I missing something or is this not available? If it's not, is it something you would like me to contribute? If it is possible with the current package, could someone point me in the right direction to implement it?

Suggestion: Add name/key property to AttachStep instead of index

I'd like to suggest that instead using index to map the attach step to the steps array, it'll be more flexible to use a key/name for the attachStep, and the steps array just referencnes the key. This way, it's easy to rearrange the order of the steps just by rearranging the steps array, instead of renumbering the AttachSteps all around the application.

Add documentation

We need to add documentation to the project's README.md. Please take the following points into account:

  • Library name and what is for
  • Requirements
  • Installation
  • Usage
  • Contribution (code of conduct)
  • License

Can't use in javaScript Project

I Wrote my project in javaScript not in typescript, it's not working.
showing the error Element type is invalid: expected a string

Support React Native Web

We want to provide support to React Native Web. To ensure the support, we should add a web version to the SpotlightExample app.

  • Make sure iOS and Android support does not break at the same time
  • Document any additional changes required to make it work
  • Include a section dedicated to the support of React Native Web on the project README.md

Spotlight style/shape

Not really an issue, but is there a way to change the style/shape of the spotlight itself? I would like to make a square rather than cricle spotlight

Start tour programmatically

Hello, thanks for this great package

Is there a way to begin the tour without calling start() via on onpress?

For example, I want my tour to automatically start the first time the user opens the app

Thanks! :)

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.