npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, πŸ‘‹, I’m Ryan HefnerΒ  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you πŸ™

Β© 2026 – Pkg Stats / Ryan Hefner

expo-ios-popover-tip

v0.1.7

Published

🧊 SwiftUI-powered Popover Tips for React Native β€” beautiful, native tooltips using TipKit πŸ’¬βš‘οΈ

Readme


✨ Features

  • 🍎 Powered by SwiftUI, ensuring native animations and rendering
  • πŸ’¬ Supports actionable tooltips with buttons
  • 🧊 Seamless glass morphism with blur and symbol support
  • πŸ” Custom dismiss & tap handlers for interactive UIs
  • 🧩 Nest React Native children inside your popover tip
  • ⚑️ High performance via Expo Modules Core

πŸš€ Installation

npx expo install expo-ios-popover-tip

Then:

cd ios && pod install

πŸ’‘ Requires Expo SDK 53+ and expo prebuild --platform ios


🧰 Getting Started (TipKit Setup)

Before using tooltips, you must reset and configure them on app launch to ensure consistent native behavior.

import React from "react";
import { Text } from "react-native";
import { ToolTipPopoverView, resetTips, configureTips } from "expo-ios-popover-tip";

export default function App() {
  const [tipsReady, setTipsReady] = React.useState(false);

  React.useEffect(() => {
    async function setup() {
      await resetTips();       // Clears any previously shown tips
      await configureTips();   // Registers new tips for the session
      setTimeout(() => setTipsReady(true), 500); // Give the system time to register
    }
    setup();
  }, []);

  if (!tipsReady) return null;

  return (
    <ToolTipPopoverView
      tooltip={{
        id: "onboarding_tip",
        title: { text: "Welcome!" },
        description: { text: "Tap this to begin." },
        actions: [{ id: "start", title: "Let’s go!" }],
      }}
    >
      <Text style={{ padding: 10, fontSize: 16 }}>Tap Me</Text>
    </ToolTipPopoverView>
  );
}

ℹ️ Note: You only need to call resetTips() and configureTips() once per app session, ideally at the root level or launch screen.


πŸ§ͺ Usage

import React from "react";
import { Text } from "react-native";
import { ToolTipPopoverView, ToolTip } from "expo-ios-popover-tip";

const tip: ToolTip = {
  id: "welcome_tip",
  title: { text: "Hello!", bold: true },
  description: { text: "This is your first popover tooltip." },
  actions: [{ id: "okay", title: "Got it" }],
};

export default function App() {
  return (
    <ToolTipPopoverView
      tooltip={tip}
      onActionPress={(action) => {
        console.log("Action tapped:", action);
      }}
      onTipDismiss={(tip) => {
        console.log("Tip dismissed:", tip);
      }}
    >
      <Text style={{ fontSize: 18, padding: 12 }}>Tap Me</Text>
    </ToolTipPopoverView>
  );
}

βš™οΈ Props

| Prop | Type | Required | Description | | --------------- | ------------------------------------------ | -------- | ----------------------------------------- | | style | StyleProp<ViewStyle> | No | Style for the container | | tooltip | ToolTip | Yes | Tooltip configuration object | | children | React.ReactNode | Yes | Content that triggers the popover | | onActionPress | (actions: Actions) => void | No | Callback when an action button is pressed | | onTipDismiss | (tip: Omit<Actions, "actionId">) => void | No | Callback when the tip is dismissed |


🧭 Sequential Tips (Tip Queue)

You can show multiple tips one after another using a simple queue and React state:

import React from "react";
import { Text } from "react-native";
import {
  ToolTipPopoverView,
  resetTips,
  configureTips,
  ToolTip,
} from "expo-ios-popover-tip";

const tipQueue: ToolTip[] = [
  {
    id: "tip1",
    title: { text: "Step 1" },
    description: { text: "This is your first tip." },
    actions: [{ id: "next", title: "Next" }],
  },
  {
    id: "tip2",
    title: { text: "Step 2" },
    description: { text: "Here's what to do next." },
    actions: [{ id: "next", title: "Next" }],
  },
  {
    id: "tip3",
    title: { text: "All done!" },
    description: { text: "You're good to go." },
    actions: [{ id: "done", title: "Finish" }],
  },
];

export default function App() {
  const [tipsReady, setTipsReady] = React.useState(false);
  const [currentTipIndex, setCurrentTipIndex] = React.useState(0);

  React.useEffect(() => {
    async function setup() {
      await resetTips();
      await configureTips();
      setTimeout(() => setTipsReady(true), 500);
    }
    setup();
  }, []);

  function handleTipEvent() {
    const nextIndex = currentTipIndex + 1;
    if (nextIndex < tipQueue.length) {
      setCurrentTipIndex(nextIndex);
    }
  }

  if (!tipsReady || currentTipIndex >= tipQueue.length) return null;

  return (
    <ToolTipPopoverView
      key={`tip-${tipQueue[currentTipIndex].id}`} // Ensures the view updates
      tooltip={tipQueue[currentTipIndex]}
      onActionPress={handleTipEvent}
      onTipDismiss={handleTipEvent}
    >
      <Text style={{ padding: 12, fontSize: 16 }}>
        Show Tip {currentTipIndex + 1}
      </Text>
    </ToolTipPopoverView>
  );
}

⚠️ Requires iOS 26 + Xcode 26 beta for displaying multiple popover tips in one session. Otherwise, only one tip will be shown by iOS system constraints.


🧩 Tooltip Object

export interface ToolTip {
  id: string;
  title: Title;
  image?: Image;
  description?: Description;
  actions?: TipActions[];
}

export interface TipActions {
  id: string;
  title: string;
}

export interface Title {
  text: string;
  foregroundColor?: string;
  size?: number;
  bold?: boolean;
}

export interface Description {
  text: string;
  foregroundColor?: string;
  size?: number;
  bold?: boolean;
}

export interface Image {
  systemName?: string; // e.g., "sparkles" (SF Symbols)
}

πŸ’‘ Customization

You can customize:

  • βœ… Title & description styles
  • βœ… SF Symbols image
  • βœ… Multiple actions
  • βœ… Dismiss callback
  • βœ… Native tap handling

πŸ“± Platform Support

  • βœ… iOS (SwiftUI)
  • ❌ Android (not supported)

⚠️ Requires iOS 17+ for TipKit support ⚠️ iOS 26 + Xcode 26 beta required for multiple popover tips


πŸ”§ Built With


πŸŽ₯ Demo

https://github.com/user-attachments/assets/c2b0e8cf-0814-40f2-b36a-66825313a6df


❀️ Contributing

Pull requests and feedback are warmly welcome! Let’s push the limits of native + React Native.


πŸ“„ License

MIT Β© rit3zh