Skip to content

jiunshinn/react-native-focus-guide

react-native-focus-guide

A React Native library that provides an elegant way to create interactive focus guides and tooltips. It allows you to highlight specific components and display tooltips with smooth animations, perfect for creating onboarding experiences, feature walkthroughs, and interactive tutorials in your React Native applications.

Features

  • 🔍 Highlight any component with a customizable dimmed overlay
  • 💬 11 tooltip anchor positions with automatic on-screen clamping & flipping
  • 📐 Real tooltip-size measurement — topCenter actually centers, right actually aligns
  • 📱 Reactive to orientation, split-screen, and web window resizing
  • 🤖 Android status-bar / nav-bar safe by default (translucent Modal — target & overlay share one coordinate space)
  • 🎯 Fabric / new-architecture safe (uses measureInWindow on the ref directly)
  • ⚡️ Smooth fade-in animation (native-driver) with configurable duration
  • 🎨 Customizable overlay color, opacity, hole padding, and hole outline (color / width / radius)
  • ☝️ Granular dismiss control (overlay / target hole)

Installation

npm install react-native-focus-guide
# or
yarn add react-native-focus-guide

No native dependencies. Pure JS — works on iOS, Android, and Web (via react-native-web).

Usage

import React, { useRef, useState } from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
import { HighlightToolTip } from 'react-native-focus-guide';

const App = () => {
  const targetRef = useRef(null);
  const [showTooltip, setShowTooltip] = useState(false);

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <TouchableOpacity
        ref={targetRef}
        onPress={() => setShowTooltip(true)}
        style={{ padding: 20, backgroundColor: '#007AFF', borderRadius: 8 }}
      >
        <Text style={{ color: 'white' }}>Click me!</Text>
      </TouchableOpacity>

      <HighlightToolTip
        targetRef={targetRef}
        visible={showTooltip}
        tooltipPosition="bottom"
        onRequestClose={() => setShowTooltip(false)}
      >
        <View
          style={{ padding: 16, backgroundColor: 'white', borderRadius: 8 }}
        >
          <Text>This is a tooltip!</Text>
        </View>
      </HighlightToolTip>
    </View>
  );
};

Tip: prefer driving the tooltip with the visible prop (above) over conditionally mounting {showTooltip && <HighlightToolTip ... />}. Both work, but visible lets the component keep its measured state between opens.

Props

Prop Type Default Description
targetRef React.RefObject<View> Ref to the component you want to highlight
children React.ReactNode Content rendered inside the tooltip
onRequestClose () => void Called when the user dismisses the tooltip
visible boolean true Show / hide the tooltip
tooltipPosition TooltipPosition 'bottom' Anchor position relative to the target
offset { x?: number; y?: number } {0, 0} Extra pixel offset applied to the computed position (clamped to screen bounds)
allowOverlap boolean false Allow the tooltip to overlap with the target (uses a small negative margin)
androidOffsetY number 0 Manual Y offset on Android. The Modal already renders translucent so coordinates align — use this only for non-standard system-bar setups
overlayColor string '#000' Dim overlay color
overlayOpacity number 0.6 Dim overlay opacity (0–1)
holePadding number 0 Extra padding (dp) around the highlighted target
holeBorderColor string undefined Outline color drawn around the highlighted target
holeBorderWidth number 0 Outline thickness (dp)
holeBorderRadius number 0 Rounded corners on the outline (dp). Use holePadding >= holeBorderRadius for the cleanest look
dismissOnPress boolean true Close when the user taps the dim overlay
dismissOnTargetPress boolean true Close when the user taps the highlighted target
animationDuration number 200 Fade-in duration in ms (0 disables the animation)

TooltipPosition

type TooltipPosition =
  | 'top'      | 'bottom'      | 'left'        | 'right'   | 'center'
  | 'topLeft'  | 'topCenter'   | 'topRight'
  | 'bottomLeft' | 'bottomCenter' | 'bottomRight';

When a tooltip would render outside the screen, the component automatically flips to the opposite side and clamps the remaining axis to keep it on-screen — preserving the horizontal alignment you chose.

Advanced usage

Custom styling

Children are rendered verbatim — style them however you like:

<HighlightToolTip
  targetRef={targetRef}
  visible={showTooltip}
  tooltipPosition="bottom"
  overlayColor="#1a1a1a"
  overlayOpacity={0.75}
  holePadding={6}
  onRequestClose={() => setShowTooltip(false)}
>
  <View
    style={{
      padding: 16,
      backgroundColor: 'white',
      borderRadius: 8,
      shadowColor: '#000',
      shadowOffset: { width: 0, height: 2 },
      shadowOpacity: 0.25,
      shadowRadius: 3.84,
      elevation: 5,
    }}
  >
    <Text style={{ fontSize: 16, color: '#333' }}>Custom styled tooltip!</Text>
  </View>
</HighlightToolTip>

Android coordinate correction

The overlay Modal is opened with statusBarTranslucent and navigationBarTranslucent so it covers the entire screen on Android. The component then adds StatusBar.currentHeight to the measured target Y, because measureInWindow on Android returns coordinates in the app's content space (below the status bar), while the translucent Modal renders from y=0 of the physical screen. The default works for the common case (Expo edge-to-edge with SafeAreaView, or apps without edge-to-edge).

If your content renders under the status bar (edge-to-edge, no safe-area padding), the auto-correction will be one status-bar too far down. Cancel it with androidOffsetY:

import { StatusBar } from 'react-native';

<HighlightToolTip
  targetRef={targetRef}
  visible={showTooltip}
  androidOffsetY={-(StatusBar.currentHeight ?? 0)}
  onRequestClose={() => setShowTooltip(false)}
></HighlightToolTip>

For other custom system-bar setups, supply a manual pixel offset:

<HighlightToolTip
  targetRef={targetRef}
  visible={showTooltip}
  androidOffsetY={-24}
  tooltipPosition="bottom"
  onRequestClose={() => setShowTooltip(false)}
></HighlightToolTip>

Positive values nudge the highlight downward; negative values upward. iOS ignores the prop.

Dismiss behavior

// Only dismiss when tapping the dim overlay, never the target
<HighlightToolTip
  visible={showTooltip}
  dismissOnTargetPress={false}
  onRequestClose={() => setShowTooltip(false)}
  ...
/>

// Programmatic-only dismissal
<HighlightToolTip
  visible={showTooltip}
  dismissOnPress={false}
  dismissOnTargetPress={false}
  onRequestClose={() => setShowTooltip(false)}
  ...
/>

Contributing

See the contributing guide to learn how to contribute to the repository and the development workflow.

License

MIT


Made with create-react-native-library

About

A React Native library that provides an elegant way to create interactive focus guides and tooltips. It allows you to highlight specific components and display tooltips with smooth animations, perfect for creating onboarding experiences, feature walkthroughs, and interactive tutorials in your React Native applications.

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors