React Native popup tip utility

Overview

react-native-tip

React Native Tip is a simple package inspired in MaterialUI-Tooltip that helps you to show a quick tip to the user and highlight some important item in your app. It is useful to explain the user some funcionality.



Demo of react-native-tip

npm version npm downloads npm licence



Installation

To install the latest version of react-native-tip you only need to run:

npm install --save react-native-tip

or

yarn add react-native-tip



Try it out

You can find the examples above on src/example.



Basic Usage

Import TipProvider and place it at the very bottom of your App.js as below:

import React from "react";
import { SafeAreaView } from "react-native";
import TipProvider from "react-native-tip";

export default class App extends React.Component {
    render() {
        return (
            <SafeAreaView style={{ flex: 1 }}>
                ... all your stuff

                <TipProvider
                    ...global options, see below
                />
            </SafeAreaView>
        );
    }
}



Show a tip

To show a tip you need to import the Tip component and wrap the component you want to highlight inside it as shown below:

import React from "react";
import { Text } from "react-native";
import { Tip } from "react-native-tip";

class App extends React.Component {
  render() {
    return (
        <Tip
            title="Title"
            body="body"
        >
            <Text
                style={{
                    padding: 10,
                    fontWeight: 'bold',
                    fontSize: 20
                }}
            >
                Show tip
            </Text>
        </Tip>
    );
  }
}

When you wrap a component inside <Tip> it becomes a touchable.
When you press it, it shows the tip automatically by default but you can change that by setting the props active = false.

OBS: if the item is already a pressable component, you have to show or close the tip manually by importing showTip(), closeTip() help functions.

import React from 'react'
import { View, StyleSheet, TouchableOpacity, Button } from 'react-native'
import { showTip, closeTip, Tip } from './Tip'
import Icon from 'react-native-vector-icons/Ionicons'

const Screen = ({ navigation }) => {
    const [_showTip, setShowTip] = React.useState(true)

    return (
        <View style={styles.container}>
            <Tip
                id='heart'
                title="Do you liked it?"
                body="Remember to hit the heart if you enjoyed the content"
                showItemPulseAnimation
                pulseColor='#ff8080'
                active={false}
            >
                <TouchableOpacity
                    onPress={() => {
                        _showTip && showTip('heart')
                        setShowTip(false)
                    }}
                    style={{ padding: 10, borderRadius: 50 }}
                >
                    <Icon name='heart' color='red' size={35}/>
                </TouchableOpacity>
            </Tip>

            <View style={{ width: 200 }}>
                <Button
                    title="Show heart tip"
                    onPress={() => showTip('heart')}
                />
            </View>
        </View>
    )
}



Show a tip tour

You can create a tour with the tips you choose by setting a list of steps and pass it as a param of showTipTour(steps) helper function.
Each step receives a series of params specified in TipStep Props below.
You can find a complete example in src/example/components/TourButton



Tip Props

Property Type Description
id string or number The tip's id, useful to control it.
title string The title text of your tip.
titleStyle TextStyle Style for the title of your tip.
body string The body text of your tip.
bodyStyle TextStyle Style for the body of your tip.
style ViewStyle Style of the item wrapper component: <Tip style={style}>.
tipContainerStyle ViewStyle Style for the tip. Use carefully, this can mess up the tip's position.
overlayOpacity number Set opacity intensity of overlay. default 0.6
renderTip ({ titleStyle:TextStyle, bodyStyle:TextStyle }) => React.Component; Set a custom component to be rendered inside your tip. You can inject your current tip's global titleStyle and bodyStyle (if you defined one in your TipProvider) props direct in your custom tip component with titleStyle and bodyStyle params.
showItemPulseAnimation boolean Show item pulse animation when tip is open.
pulseColor string Set pulse animation color.
dismissable boolean Allow auto dismiss on touch overlay.
active boolean Default = true If true the item becomes pressable and shows the tip automatically when pressed. OBS: if the item is already a pressable component, you should show or close it manually by using showTip(), closeTip() help functions.
onPressItem () => void Trigger your custom action on item press.
onTipPress () => void Trigger your custom action on tip press.
onDismiss () => void Override dismiss natural action.



TipProvider Props

You can set a default style for all your tips with the following:

Property Type Description
tipContainerStyle ViewStyle Set global style for the tip wrapper
titleStyle TextStyle Set global style for the title of your tip
bodyStyle TextStyle Set global style for the body of your tip.
overlayOpacity number Set global opacity intensity of overlay. default 0.6
showItemPulseAnimation boolean Set global pulse animation on item when tip is open.
darkMode boolean When true set a dark custom color scheme for your tip. It can be overwritten by titleStyle and bodyStyle props.
prevButtonLabel string Label for Prev action button on tip tour mode.
nextButtonLabel string Label for Next action button on tip tour mode.
closeButtonLabel string Label for Close action button on tip tour mode.
prevNextButtonStyle ViewStyle Style for Next, Prev, Close action buttons on tip tour mode.
prevNextTextStyle TextStyle Style for Next, Prev, Close action buttons text on tip tour mode.



Helper functions

Property Type Description
showTip (tipId?: string, delay?: number) => void Show your tip, can be called anywhere in your code. * You can show a specific tip by passing its id. * You can delay your tip's appearing by passing a delay number in milliseconds, useful to await async tasks live navigate to another screen, default=0
closeTip ()=>void Close the current opened tip, can be called anywhere in your code.
showTipTour (steps: ITipStep[])=>void Set a tip tour sequence.


TipStep Props

Property Type Description
id string Current tip id, required
prevId string Previous tip id, optional
nextId string Next tip id, optional
delay number Timeout before triggering the tip change to next or previous one.
prevAction () => void Action to be executed right before Prev button is pressed. Use it with delay prop for async tasks.
nextAction () => void Action to be executed right before Next button is pressed. Use it with delay prop for async tasks.



License

MIT

Comments
  • Crash with react navigation

    Crash with react navigation

    Thanks for your lib! I have a crash when I use it with react-navigation (v5). If I use Tip on a screen in a Stack Navigator for example. Here the following step:

    1. Go to the screen with Tip
    2. Press on Tip => it's working as expected
    3. Go back in navigation stack
    4. Return to the screen with Tip
    5. Press on Tip, this error appear:
    Invariant Violation: [1083,"RCTView",71,{"accessible":true,"position":"absolute","top":"<<NaN>>","left":"<<NaN>>","transform":[{"translateX":"<<NaN>>"},{"translateY":"<<NaN>>"}],"opacity":1,"focusable":true}] is not usable as a native method argument
    
    This error is located at:
        in RCTView (at View.js:34)
        in View (at createAnimatedComponent.js:165)
        in AnimatedComponent (at createAnimatedComponent.js:215)
        in ForwardRef(AnimatedComponentWrapper) (at TouchableOpacity.js:224)
        in TouchableOpacity (at TouchableOpacity.js:302)
        in ForwardRef (at TipProvider.js:394)
        in TipProvider (at App.tsx:139)
        in App (at renderApplication.js:45)
        in RCTView (at View.js:34)
        in View (at AppContainer.js:106)
        in RCTView (at View.js:34)
        in View (at AppContainer.js:132)
        in AppContainer (at renderApplication.js:39)
    

    Crash on android and ios.

    opened by rdhox 10
  • Avoid double fade

    Avoid double fade

    Currently, when pressing anywhere on the screen to dismiss the tip, the tip fades twice. Removing the fade on the modal itself fixes that, since there is already a fade animation in the animateOut function.

    opened by noway 1
  • The tip image is duplicated only on Android devices

    The tip image is duplicated only on Android devices

    This is only happening on android devices when i click on the button that is wrapped in . It showing the duplicated button right below the wrapped button

    This is the code:

    <Tip
     id={tooltipId}
     body={FAVORITE.PRICE_MAY_CHANGE}
     bodyStyle={styles.tooltipCaption}
     active={false}
     onDismiss={() => this.dismissPriceTooltip(tooltipId)}
     tipContainerStyle={styles.tooltipStyle}
     overlayOpacity={-1}
    >
     <TouchableOpacity onPress={() => this.showHidePriceTooltip(tooltipId)}>
      <Image
       source={toolTipIcon}
       style={styles.tooltipIcon}
      />
     </TouchableOpacity>
    </Tip>
    

    And this is the duplicated button on android:

    Screenshot 2022-12-23 at 11 08 22

    I think It's happening because of the {this.renderItem()} on tipProvider.js

    Could you check on this? Thanks!

    opened by MichaelAmadheo 0
  • The tip is misplaced when orientation changes

    The tip is misplaced when orientation changes

    How to reproduce

    1. click tip
    2. close
    3. go from portrait to landscape
    4. click tip again
    5. the tip is misplaced

    image

    How do I make react-native-tip to properly handle orientation changes?

    opened by noway 3
  • Tips are not found in different screen from currentTip during TipTour

    Tips are not found in different screen from currentTip during TipTour

    Thank you for sharing this library. Very insightful.

    I think there is a limitation in TipTour implementation. It fails to find nextTips when they are present in a different screen which is not loaded (Tip is not registered) until we navigate to that screen.

    I think we should call nextAction/prevAction before finding the tip by id in the registry. So that once nextAction is called,

    • we navigate to the screen,
    • the tip is registered
    • then we can find it after some predefined delay (depending time for navigation animation + set layout)
    opened by griimick 0
  • Invariant Violation: [2963,>","left":75,"transform":[{"translateX":-51},{"translateY":-22}],"justifyContent":"center","alignItems":"center"}] is not usable as a native method argument">

    Invariant Violation: [2963,"RCTView",11,{"position":"absolute","width":102,"height":44,"top":"<>","left":75,"transform":[{"translateX":-51},{"translateY":-22}],"justifyContent":"center","alignItems":"center"}] is not usable as a native method argument

    Experiencing this error:

    Invariant Violation: [2963,"RCTView",11,{"position":"absolute","width":102,"height":44,"top":"<<NaN>>","left":75,"transform":[{"translateX":-51},{"translateY":-22}],"justifyContent":"center","alignItems":"center"}] is not usable as a native method argument
    
    This error is located at:
        in RCTView (at TipProvider.js:416)
        in RCTView (at AppContainer.js:101)
        in RCTView (at AppContainer.js:119)
        in AppContainer (at Modal.js:250)
        in RCTView (at Modal.js:271)
        in RCTModalHostView (at Modal.js:258)
        in Modal (at TipProvider.js:439)
        in TipProvider (created by App)
        in RCTSafeAreaView (at SafeAreaView.js:55)
        in SafeAreaView (created by App)
        in App (at renderApplication.js:40)
        in RCTView (at AppContainer.js:101)
        in RCTView (at AppContainer.js:119)
        in AppContainer (at renderApplication.js:39)
    
    fn
        NativeModules.js:137:10
    Component.prototype.setState
        react.development.js:325:31
    showTip
        TipProvider.js:41:8
    tryCatch
        runtime.js:63:44
    invoke
        runtime.js:293:30
    tryCatch
        runtime.js:63:44
    invoke
        runtime.js:154:28
    PromiseImpl.resolve.then$argument_0
        runtime.js:164:19
    tryCallOne
        core.js:37:14
    setImmediate$argument_0
        core.js:123:25
    

    react-native info:

    yarn run react-native info                                                                                                                                                                                                  *[ch8764/native-new-design]
    yarn run v1.22.10
    $ /Users/ilia/myapp/myapp/node_modules/.bin/react-native info
    warn Your project is using deprecated "rnpm" config that will stop working from next release. Please use a "react-native.config.js" file to configure the React Native CLI. Migration guide: https://github.com/react-native-community/cli/blob/master/docs/configuration.md
    warn The following packages use deprecated "rnpm" config that will stop working from next release:
      - react-native-comparison-slider: https://npmjs.com/package/react-native-comparison-slider
      - react-native-orientation: https://github.com/yamill/react-native-orientation#readme
      - react-native-video: https://npmjs.com/package/react-native-video
      - react-native-zip-archive: https://github.com/mockingbot/react-native-zip-archive
    Please notify their maintainers about it. You can find more details at https://github.com/react-native-community/cli/blob/master/docs/configuration.md#migration-guide.
    info Fetching system and libraries information...
    System:
        OS: macOS 11.3.1
        CPU: (8) arm64 Apple M1
        Memory: 269.39 MB / 16.00 GB
        Shell: 5.8 - /bin/zsh
      Binaries:
        Node: 16.5.0 - /var/folders/85/2xpmzxms1tsgzr9nqnhszzfw0000gn/T/yarn--1628129877401-0.3539187398275403/node
        Yarn: 1.22.10 - /var/folders/85/2xpmzxms1tsgzr9nqnhszzfw0000gn/T/yarn--1628129877401-0.3539187398275403/yarn
        npm: 7.19.1 - /opt/homebrew/bin/npm
        Watchman: 2021.06.07.00 - /opt/homebrew/bin/watchman
      SDKs:
        iOS SDK:
          Platforms: iOS 14.5, DriverKit 20.4, macOS 11.3, tvOS 14.5, watchOS 7.4
        Android SDK:
          API Levels: 23, 25, 27, 28, 29, 30
          Build Tools: 28.0.3, 29.0.2, 29.0.3, 30.0.2, 30.0.3
          System Images: android-29 | Intel x86 Atom_64, android-29 | Google APIs Intel x86 Atom, android-30 | Google APIs Intel x86 Atom
      IDEs:
        Android Studio: 4.1 AI-201.8743.12.41.7199119
        Xcode: 12.5.1/12E507 - /usr/bin/xcodebuild
      npmPackages:
        react: 16.9.0 => 16.9.0
        react-native: 0.61.5 => 0.61.5
    ✨  Done in 10.97s.
    
    

    setup: App.tsx:

    
    	render(): JSX.Element {
    		return (
    			<SafeAreaView style={{flex:1}}>
    				<Provider store={store}>
    					<Main />
    				</Provider>
    				<TipProvider 
    				/>
    			</SafeAreaView>
    		)
    	}
    

    component:

    
    	render() {
    		return (
    			<>
    			<Tip
    				id="heart"
    				title="Title"
    				body="body"
    			>
    				<Text
    					style={{
    						padding: 10,
    						fontWeight: 'bold',
    						fontSize: 20
    					}}
    				>
    					Show tip
    				</Text>
    			</Tip>
    ...
    
    						<Button
    							title="Show heart tip"
    							onPress={() => showTip('heart')}
    						/>
    
    ...
    </>
    )
    }
    
    opened by noway 1
Owner
Maicon Gilton de Souza Freire
Maicon Gilton de Souza Freire
Fully typed hooks and utility functions for the React Native StyleSheet API

react-native-style-utilities Fully typed hooks and utility functions for the React Native StyleSheet API npm i react-native-style-utilities ESLint Set

Marc Rousavy 73 Dec 17, 2022
null 136 Dec 30, 2022
📋 React Hooks for forms validation (Web + React Native)

English | 繁中 | 简中 | 日本語 | 한국어 | Français | Italiano | Português | Español | Русский | Deutsch | Türkçe Features Built with performance and DX in mind

React Hook Form 32.4k Dec 29, 2022
A personal project, made with React, React Native, Typescript and some of the most used front-end libraries.

A personal project, made with React, React Native, Typescript and some of the most used front-end libraries.

Alvaro Junior 1 Jul 23, 2022
A React utility belt for function components and higher-order components.

A Note from the Author (acdlite, Oct 25 2018): Hi! I created Recompose about three years ago. About a year after that, I joined the React team. Today,

Andrew Clark 14.8k Jan 4, 2023
Free React Native library to display local notifications.

React-Native NotiFREE ⚛ React Native library to display local notifications. A FREE alternative to React Native NotiFEE. Why? Nobody can remove the gr

Douglas Nassif Roma Junior 23 Nov 10, 2022
A collection of sample apps built using GetStream and React Native

React Native samples [ Built with ♥ at Stream ] This repo contains projects and samples developed by the team and Stream community, using React Native

Stream 93 Jan 8, 2023
Boilerplate to build Cross-Platform Apps with Expo and React Native

Expo and React Native Boilerplate Boilerplate to build Cross-Platform Apps with Expo and React Native What are you going to find in this boilerplate E

José Ferrer 26 Apr 29, 2022
A social app concept with React Native

Social App Concept-React Native ?? A simple social app concept with react native. Improving day by day. Star ⭐ the repo if you like what you see ?? .

Olaifa Boluwatife 30 Dec 31, 2022
Further split the React Native code based on Metro build to improve performance, providing `Dll` and `Dynamic Imports` features

React-Native Code Splitting Further split the React Native code based on Metro build to improve performance, providing Dll and Dynamic Imports feature

Wuba 126 Dec 29, 2022
React Native & Expo music player application UI

Would you like to support me? Musicont React Native & Expo music player application UI Demo: https://expo.io/@jsxclan/musicont APK: Download on Google

JSX Clan 82 Dec 14, 2022
uber-eats-clone react native

Uber Eats Clone Uber Eats Clone React Native Tools and technology react-native Stripe payment checkout expo tailwind css yelp API Firebase (Authentica

Khalid Saifullah 18 Dec 7, 2022
A React Native starter template project with built-in navigation & redux toolkit.

react-native-template A React Native starter template project with built-in navigation & redux toolkit. What's included? @react-native-async-storage/a

Manish Bista 8 Oct 29, 2022
A react native component that lets you build a dynamic expandable chips list.

React Native Expandable Chips List A react native component that lets you build a dynamic expandable chips list. Installation Run npm install react-na

Daniel Cocos 13 Sep 23, 2022
🚀 Aplicação mobile com React Native produzida durante o Next Level Week #05

✨ Tecnologias Esse projeto foi desenvolvido com as seguintes tecnologias: React Native Typescript Expo ?? Projeto Aplicativo para lhe ajudar a lembrar

Danilo Alexandrino 11 May 28, 2022
🧍‍♂️ React Native + Next.js, unified.

Solito A library dedicated to unifying React Native with Next.js, primarily focused on navigation. This is still experimental. Docs & Examples ?? Docu

Fernando Rojo 2k Jan 9, 2023
The Tesla Clone built in React Native FrameWork

Tesla Clone The Tesla Clone built in React Native FrameWork Features Flat Infinite Scroll List View with animations. Design is responsive to different

LakhanKumawat ᵖ⁺ 2 Feb 10, 2022
PDF-to-TEXT using Rest7 API REACT-NATIVE

PDF-to-TEXT-using-Rest7-API-REACT-NATIVE- I have made a Demo App to select PDF from documents and convert it into text than Display in ( component) us

Sahil saiyed 0 Nov 22, 2022
This project is a Vegan recipe application. I created with React Native. Check out VeganRecipe now for recipe app

VeganRecipe ?? ?? ?? ?? Hello! This project is a Vegan recipe application. I created with React Native. Check out VeganRecipe now for recipe app. ?? ?

Murat 4 Mar 27, 2022