1 slot open this monthBy the makers of shadcnregistryWe built shadcnregistry. Now we build your product.Book a callCheck availability
1 slot open this monthAI features?We build AI features into your product.Book a callCheck availability
1 slot open this month🚨 Slop police🚨 Slop police: we clean up vibe-coded apps.Report itReport your app
shadcnregistry
shadcnregistry
RegistryHealthInspect
Terms of ServicePrivacy Policy
  1. Registries
  2. pulld
  3. Product Tour

Product Tour

ui

A guided tour of the real screen: a card that walks through your own UI, dimming the page and lighting up the one control each step is about, with Back and Next, a progress count, a way out, and placement that flips to whichever side of the target has room. The spotlight is re-measured every frame, so it follows a target that slides in with a panel, shifts when a web font swaps in, or gets replaced by React — and it stops lighting anything at all when the target is not there, instead of leaving a bright square over empty page. Reach for it on a first login and after a release: SaaS onboarding, a redesigned admin layout people have to be walked through, an editor's panels and shortcuts, an internal tool nobody reads the docs for, the introduction to a multi-step settings wizard, a feature announcement that has to point at the feature, a checkout or booking flow being explained to new staff, and a dashboard whose numbers need one pass of explanation. Common asks it answers: "product tour react", "onboarding tour component", "guided tour react", "coachmark react", "spotlight onboarding overlay", "walkthrough component shadcn", "shadcn product tour", "driver.js alternative react", "react-joyride alternative", "intro.js for react", "shepherd.js react", "feature tour with tooltips", "highlight an element and explain it", "dim the page except one element", "tour that waits for a lazy-loaded element", "tour step that lets the user click the highlighted button", "resume a product tour where the user left off", "accessible product tour keyboard", "onboarding tour without floating-ui". Official shadcn/ui has nothing for this: coachmark, spotlight, walkthrough, driver.js, tourStep, onboardingStep, highlightTarget and the word tour itself are each zero hits across all 62 of its fetchable items (measured 2026-09-26), and so are getBoundingClientRect, IntersectionObserver, ResizeObserver and clip-path — nothing in it measures the page at all. Its popover is a card tied to one element with no order, no progress and no Next; its dialog takes over the screen rather than pointing at a part of it; and its tooltip is for a label, not for a paragraph with buttons in it. Distinct from the pulld pieces it sits beside: step-indicator draws progress and points at nothing, keyboard-shortcuts and command-palette list what is possible rather than showing it in place, empty-state is what a screen says before there is anything to tour, announcement-bar tells everyone at once without pointing, and highlight-text marks words inside a string. One file, no floating-ui or popper, no portal, no react-dom import. Six things separate it from the version built out of a popover and an array index. First, the target does not hold still: a tour usually begins by opening something, and a panel sliding open with a CSS transition moves its target through a hundred positions while firing no event at all — so the rectangle is taken every frame rather than once per step, and React is only told when a number actually changed. Second, absent and gone and invisible are one state: an element that has left the document still answers getBoundingClientRect with the rectangle it had on the way out, and one inside display:none answers all zeros, which draws a spotlight in the top-left corner of the page — both count as nothing to point at, the same as a step whose code-split panel has not loaded yet, and that step degrades to a centred card and reports itself after a wait instead of pointing at a hole. Third, the hole is four rectangles, not a trick: a box-shadow spread is not a hit area, so the page around the target stays clickable while the target alone is blocked, i.e. exactly backwards, and a clip-path makes clickability a property of a path string; four elements tile the viewport exactly (no seam, no overlap, no gap to click through), and the target is made inert again by one more rectangle over the hole. Fourth, aria-modal is a lie on an interactive step: a step that has just told someone to press the highlighted button cannot also tell a screen reader that everything outside the card does not exist, so the attribute goes when the hole is live. Fifth, the same for the keyboard: the tab scope is the card alone on an inert step and the target's controls plus the card's on a live one, target first, because the thing a person was just asked to click should not be several stops past a button called Next. Sixth, placement and resume: a requested side is abandoned when the card does not fit there (otherwise Next ends up off the bottom of a laptop window), the cross axis is clamped instead of blindly centred, and where somebody stopped is reported to you to store rather than written to localStorage — a per-device flag runs the tour again on the phone — with a saved step id that no longer exists starting the tour over rather than showing a blank screen.

pnpm dlx shadcn@latest add "https://pulld.pages.dev/r/product-tour.json"
Premium blocks for shadcn/uiShadcnblocks.com · AffiliateExplore
  • lucide-react
    components/ui/product-tour.tsx