Angular 17+ standalone help/spotlight tour library — highlight elements (spotlight-only) or show guided cards with next/prev controls. Lightweight, a11y‑friendly, and SSR‑aware.
- 🧩 Standalone Angular component (no NgModule) + simple service API
- 🔦 Spotlight-only focus or full Card tour mode
- ⌨️ Keyboard nav: ← → / Enter / Esc
- 🕒 Auto‑advance between steps (
autoAdvanceMs) with optional pause on hover - 🖱 Click‑through control on mask (block/allow background clicks)
- 🟢 Shape presets:
rectorcircle, per‑step padding + border radius - 🧭 Viewport aware card positioning (top/bottom/left/right/auto)
- ♿ Accessible (dialog semantics in card mode, close with Esc)
- 🧪 SSR‑friendly (no direct DOM in service; guarded usage in component)
npm i ngxsmk-help-tourRequires Angular 17+.
Add the overlay host once near the root of your app:
<ngxsmk-help-tour></ngxsmk-help-tour>Use focus(target, options?) to highlight any element without showing a card:
import { Component } from '@angular/core';
import { HelpTourService } from 'ngxsmk-help-tour';
@Component({ selector: 'app-demo', standalone: true, template: `
<button id="hero-cta" (click)="highlight()">Hero CTA</button>
<ngxsmk-help-tour></ngxsmk-help-tour>
`})
export class DemoComponent {
constructor(private tour: HelpTourService) {}
highlight() {
this.tour.focus('#hero-cta', {
padding: 12,
shape: 'rect', // or 'circle'
maskOpacity: 0.7,
// autoAdvanceMs: 2000, // uncomment to auto-close after 2s
allowClose: true,
});
}
}Define steps and start a guided tour with titles/content and navigation.
import { Component } from '@angular/core';
import { HelpTourComponent, HelpTourService, TourStep } from 'ngxsmk-help-tour';
@Component({
selector: 'app-card-demo',
standalone: true,
imports: [HelpTourComponent],
template: `
<button id="hero-cta" (click)="startTour()">Start Tour</button>
<a id="profile-btn">Profile</a>
<div id="side-nav">Sidebar</div>
<ngxsmk-help-tour></ngxsmk-help-tour>
`
})
export class CardDemoComponent {
constructor(private tour: HelpTourService) {}
startTour() {
const steps: TourStep[] = [
{ id: 'welcome', target: '#hero-cta', title: 'Welcome', content: 'Click here to begin', placement: 'bottom', padding: 10 },
{ id: 'nav', target: '#side-nav', title: 'Navigation', content: 'Use the sidebar to switch sections', placement: 'right' },
{ id: 'profile', target: '#profile-btn', title: 'Profile', content: 'Manage your account here', placement: 'top', shape: 'circle' }
];
this.tour.start(steps, { mode: 'card', maskOpacity: 0.6, storageKey: 'help-tour-v1' });
}
}start(steps: TourStep[], options?: TourOptions)— start a tourfocus(target, options?)— spotlight‑only single step (no card)next()/prev()/close(completed?: boolean)goTo(indexOrId)— jump to a specific stepstartIfNotCompleted(steps, options?)— respectsstorageKeysetOptions(partial)— update global options at runtime- Signals (readonly):
active,current,currentIndex,count,options
{
id: string;
target: string | ElementRef<HTMLElement>;
title?: string; // (card mode)
content?: string; // (card mode)
placement?: 'auto'|'top'|'bottom'|'left'|'right';
offset?: number; // gap between card and target
padding?: number; // spotlight padding
shape?: 'rect'|'circle';
borderRadius?: number|string;
beforeEnter?: () => void|Promise<void>;
beforeLeave?: () => void|Promise<void>;
canProceed?: () => boolean|Promise<boolean>;
}{
mode?: 'spotlight'|'card';
maskOpacity?: number; // 0..1
allowClose?: boolean; // esc / mask click
keyboard?: boolean; // arrow keys / enter / esc
clickThrough?: boolean; // allow background clicks
autoAdvanceMs?: number; // auto-next/close after ms
pauseOnHover?: boolean; // pause auto-advance on hover
scrollBehavior?: 'smooth'|'auto';
storageKey?: string; // mark completed in localStorage
waitForSelectorMs?: number; // poll time for late targets
theme?: 'light'|'dark';
}Customize via CSS variables (global or scoped to the host):
ngxsmk-help-tour {
--tour-bg: #111827; /* card bg (card mode) */
--tour-fg: #fff; /* card text */
--tour-accent: #22d3ee; /* buttons & spotlight border */
--tour-mask: rgba(0,0,0,.60);
--tour-radius: 12px; /* card radius */
--tour-shadow: 0 10px 30px rgba(0,0,0,.25);
}Create a quick demo app and serve:
ng generate application ngxsmk-help-tour-demo --standalone --routing=false --style=scss
ng serve ngxsmk-help-tour-demo- For spotlight tours, consider
autoAdvanceMsandclickThrough:falsefor guided focus. - If a target may render later (lazy components/routes), set
waitForSelectorMs. - Use
storageKeyto run once per user.
angular · angular17 · angular-standalone · onboarding · product-tour · spotlight · overlay · a11y · ngxsmk