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

@tent-official/react-walkthrough

v1.1.95

Published

Lightweight React walkthrough/tour component with auto-positioning, dependency chains, and smooth animations

Readme

@tent-official/react-walkthrough

Lightweight React walkthrough/tour component with auto-positioning, dependency chains, and smooth animations.

Features

  • SVG-based spotlight overlay with smooth animated transitions
  • Auto-positioning popover (top/bottom/left/right) with viewport detection
  • Dependency chains — start a walkthrough only after another completes
  • Conditional start — startWhenCondition prop to gate walkthrough on custom logic (e.g. data loaded)
  • Auto-cleanup on navigation — highlight is automatically removed when the component unmounts (e.g. browser back/forward)
  • Customizable labels, colors, and layout
  • Reset and replay walkthroughs without page refresh
  • Portal-based rendering (works inside modals)
  • Zero external dependencies (only React as peer dep)

Installation

npm install @tent-official/react-walkthrough
# or
yarn add @tent-official/react-walkthrough

Peer Dependencies

Make sure these are installed in your project:

npm install react react-dom

Quick Start

import { useWalkthrough, WalkthroughOverlay } from "@tent-official/react-walkthrough";

function App() {
  useWalkthrough({
    name: "intro-tour",
    delay: 500, // wait 500ms before highlighting the first step
    steps: [
      {
        el: "welcome-title",
        title: "Welcome!",
        description: [{ description: "This is the main title of your app." }],
      },
      {
        el: "nav-menu",
        title: "Navigation",
        description: [{ description: "Use this menu to navigate around." }],
        position: "right",
      },
    ],
  });

  return (
    <div>
      <h1 id="welcome-title">My App</h1>
      <nav id="nav-menu">...</nav>
      <WalkthroughOverlay />
    </div>
  );
}

API

useWalkthrough(options)

Hook to register a walkthrough tour.

| Option | Type | Default | Description | | --- | --- | --- | --- | | name | string | required | Unique name for this walkthrough | | steps | IWalkthroughStep[] | required | Array of steps | | storageSuffix | string | "" | Storage suffix for localStorage | | dependsOn | string[] | [] | Walkthrough names that must complete first | | startWhenCondition | boolean \| () => boolean | undefined | Additional condition that must be true for the walkthrough to start. Both dependsOn AND startWhenCondition must be satisfied. Example: startWhenCondition: list.length > 0 | | onWalkthroughComplete | (name: string) => void | — | Callback when walkthrough completes (both finish and skip) | | handleWhenLastStep | () => void | — | Callback fired only when the user clicks "Done" on the last step (not on skip). Useful for triggering navigation (e.g. router.push) | | isShowSkip | boolean | true | Show skip button | | isShowPrev | boolean | true | Show back button (can be overridden per step) | | isShowStep | boolean | true | Show step counter e.g. "1/3" (can be overridden per step) | | nextLabel | string | "Next" | Next button label (can be overridden per step) | | prevLabel | string | "Back" | Previous button label (can be overridden per step) | | skipLabel | string | "Skip" | Skip button label (can be overridden per step) | | delay | number | 0 | Delay in ms before highlighting the first step. During delay, a dark overlay is shown | | doneLabel | string | "Done" | Done button label (last step) | | containerElement | string | — | DOM element ID of the scrollable container (e.g. a drawer). When provided, scrolls within this container instead of the window | | animationSpeed | number | 350 | Base animation speed (ms) used to calculate transition duration from distance | | displayTotal | number | — | Override the total step count displayed in the step counter (display-only, does not affect logic) | | displayStepOffset | number | 0 | Offset added to the displayed current step number (display-only, does not affect logic). e.g. displayStepOffset: 3 with 3 real steps shows 4/total → 5/total → 6/total | | isClearLastPositionOnEnd | boolean | false | When true, clears the saved last highlight position when the tour ends. This prevents the next tour from animating its highlight from this tour's last position |

Returns: { start: () => void }

IWalkthroughStep

| Property | Type | Default | Description | | --- | --- | --- | --- | | el | string | required | DOM element ID to highlight (with or without # prefix) | | title | string | — | Popover title | | description | IStepDescription[] | required | Description blocks | | position | "top" \| "bottom" \| "left" \| "right" | auto | Preferred popover position | | padding | number | 8 | Padding around highlighted element (px) | | borderRadius | number | 10 | Border radius of highlight cutout (px) | | width | number \| string | "auto" | Popover width | | height | number \| string | — | Popover height | | triggerElOnNext | string \| boolean | — | When set, clicking "Next" triggers a click on an element. If a string (element ID), clicks that element; if true, clicks the step's own target element | | isShowPrev | boolean | — | Override tour-level isShowPrev for this step | | isShowStep | boolean | — | Override tour-level isShowStep for this step | | nextLabel | string | — | Override tour-level nextLabel for this step | | prevLabel | string | — | Override tour-level prevLabel for this step | | skipLabel | string | — | Override tour-level skipLabel for this step |

IStepDescription

| Property | Type | Description | | --- | --- | --- | | title | string | Optional label for this block | | description | ReactNode | Description content | | direction | "row" \| "column" | Layout direction |

<WalkthroughOverlay />

Place this component once at the root of your app. It renders via React Portal into document.body.

| Prop | Type | Default | Description | | --- | --- | --- | --- | | $popoverPadding | number | 12 | Inner padding of popover (px) | | $popoverBorderRadius | number | 8 | Border radius of popover (px) | | $popoverGap | number | 12 | Gap between highlight and popover (px) | | $popoverMinWidth | number | 275 | Minimum width of the popover (px) | | $animationSpeed | number | 350 | Base animation speed (ms). Actual duration is calculated from distance — shorter distance = faster, longer distance = slower. Lower value = faster overall, higher = slower overall | | nextColor | string | "#000" | Custom next button color | | prevColor | string | — | Custom previous button color | | skipColor | string | — | Custom skip button color |

resetWalkthrough(options?)

Reset walkthroughs so they can be replayed without page refresh.

import { resetWalkthrough } from "@tent-official/react-walkthrough";

resetWalkthrough({
  storageSuffix: "my-app",
  walkthroughList: ["intro-tour", "feature-tour"],
});

| Option | Type | Default | Description | | --- | --- | --- | --- | | storageSuffix | string | "" | Storage suffix | | walkthroughList | string[] | [] | Names of walkthroughs to reset |

getCompletedWalkthroughs(options?)

Get a list of all completed walkthrough names. Returns an array of walkthrough name strings that have been marked as done.

import { getCompletedWalkthroughs } from "@tent-official/react-walkthrough";

const list = getCompletedWalkthroughs({ storageSuffix: "my-app" });
// => ["intro-tour", "feature-tour"]

| Option | Type | Default | Description | | --- | --- | --- | --- | | storageSuffix | string | "" | Storage suffix matching the one used in useWalkthrough |

Dependency Chains

You can create sequential walkthroughs using dependsOn:

// This runs first
useWalkthrough({
  name: "intro-tour",
  storageSuffix: "my-app",
  steps: [/* ... */],
});

// This starts automatically after intro-tour completes
useWalkthrough({
  name: "advanced-tour",
  storageSuffix: "my-app",
  dependsOn: ["intro-tour"],
  steps: [/* ... */],
});

Conditional Start

Use startWhenCondition to gate a walkthrough on custom logic. The walkthrough will only start when both dependsOn (if any) and startWhenCondition are satisfied:

function Dashboard({ items }) {
  // Won't start until items are loaded AND intro-tour is done
  useWalkthrough({
    name: "items-tour",
    storageSuffix: "my-app",
    dependsOn: ["intro-tour"],
    startWhenCondition: items.length > 0,
    steps: [/* ... */],
  });

  // Also accepts a function
  useWalkthrough({
    name: "profile-tour",
    startWhenCondition: () => document.getElementById("profile-btn") !== null,
    steps: [/* ... */],
  });

  return <div>...</div>;
}

When startWhenCondition is undefined (default), only dependsOn is checked — backward compatible.

Auto-Cleanup on Navigation

The walkthrough highlight is automatically removed when the component that registered it unmounts. This means:

  • Pressing browser back/forward properly clears the overlay
  • Route changes (e.g. React Router, Next.js) clean up automatically
  • No stale highlights left on screen after navigation

No extra configuration needed — this works out of the box.

Keyboard Blocking

While a walkthrough is active, the following keyboard keys are automatically blocked to prevent users from accidentally interacting with highlighted elements behind the overlay:

| Key | Reason | | --- | --- | | Enter | Prevents triggering click on focused elements | | Space | Prevents triggering click on buttons/checkboxes | | Escape | Prevents closing dialogs/dropdowns being highlighted | | Backspace | Prevents browser back navigation or input deletion | | Delete | Prevents deleting content in inputs | | Tab | Prevents moving focus to elements behind the overlay |

Walkthrough buttons (Next / Back / Skip / Done) remain fully functional — only keys targeting elements outside the walkthrough are blocked.

Auto-Positioning

The popover automatically positions itself to stay within the viewport:

  1. If position is specified, it tries that position first
  2. If it doesn't fit, it falls back to: bottom → top → right → left
  3. If nothing fits perfectly, it picks the direction with the most available space

The popover also waits for the target element to be scrolled into view before appearing.

License

MIT