Guided Tour
optics/guided-tourFreeComponent
A guided tour component for onboarding users.
See it running
Open the demo on optics
optics.agusmayol.com.ar/components/guided-tourInstall it
npx shadcn@latest add https://optics.agusmayol.com.ar/r/guided-tour.jsonSource
1"use client";23import * as React from "react";4import { Popover as PopoverPrimitive } from "@base-ui/react/popover";5import {6 Popover,7 PopoverTrigger,8 PopoverContent,9} from "@/registry/optics/popover";10import { cn } from "@/registry/optics/lib/utils";11import { Button } from "@/registry/optics/button";12import { X } from "lucide-react";1314const GuidedTourContext = React.createContext({15 activeTour: null,16 setActiveTour: () => {},17 currentStep: 0,18 setCurrentStep: () => {},19 steps: [],20 setSteps: () => {},21 totalSteps: 0,22});2324function GuidedTourProvider({ children = null, ...props }) {25 const [activeTour, setActiveTour] = React.useState(null);26 const [currentStep, setCurrentStep] = React.useState(0);27 const [steps, setSteps] = React.useState([]);28 const [totalSteps, setTotalSteps] = React.useState(0);2930 const contextValue = React.useMemo(31 () => ({32 activeTour,33 setActiveTour,34 currentStep,35 setCurrentStep,36 steps,37 setSteps,38 totalSteps,39 setTotalSteps,40 }),41 [activeTour, currentStep, steps, totalSteps],42 );4344 return (45 <GuidedTourContext.Provider value={contextValue} {...props}>46 {children}47 </GuidedTourContext.Provider>48 );49}5051function useGuidedTour() {52 const context = React.useContext(GuidedTourContext);53 if (!context) {54 throw new Error("useGuidedTour must be used within GuidedTourProvider");55 }56 return context;57}5859const GuidedTourOverlay = React.forwardRef(({ className, ...props }, ref) => {60 const { activeTour } = useGuidedTour();6162 if (!activeTour) return null;6364 return (65 <div66 ref={ref}67 className={cn(68 "fixed inset-0 z-[100] bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",69 className,70 )}71 {...props}72 />73 );74});75GuidedTourOverlay.displayName = "GuidedTourOverlay";7677function GuidedTour({ children = null, ...props }) {78 return (79 <div data-slot="guided-tour" {...props}>80 {children}81 </div>82 );83}8485function GuidedTourTrigger({86 tourId = "",87 children = null,88 className = "",89 render = null,90 ...props91}) {92 const { onClick, ...restProps } = props;93 const { setActiveTour, setCurrentStep, setTotalSteps } = useGuidedTour();9495 const handleClick = (event) => {96 if (onClick) {97 onClick(event);98 }99100 if (event?.defaultPrevented) return;101102 const tourSteps = document.querySelectorAll(103 `[data-tour="${tourId}"][data-step]`,104 );105 const sortedSteps = Array.from(tourSteps).sort((a, b) => {106// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from optics
All 79 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | optics | Components | Free | 5 deps | |
| Alertalert | optics | Components | Free | 4 deps | |
| Alert Dialogalert-dialog | optics | Components | Free | 4 deps | |
| Aspect Ratioaspect-ratio | optics | Components | Free | 2 deps | |
| Auto Heightauto-height | optics | Components | Free | 3 deps | |
| Avataravatar | optics | Components | Free | 3 deps | |
| Badgebadge | optics | Components | Free | 4 deps | |
| Breadcrumbbreadcrumb | optics | Components | Free | 4 deps |
