@tour-kit/hints
Add contextual hint beacons and hotspots that highlight features and guide users without interrupting their workflow
LLM Context File
Working with an AI assistant? Download the context file for @tour-kit/hints and paste it into your conversation for accurate code generation.
@tour-kit/hints
A lightweight library for adding contextual hints to your React application. Hints are persistent UI elements that guide users to features without interrupting their flow.
Why Hints?
Unlike tours (which are sequential and require user attention), hints are:
- Non-blocking - Users can interact with your app while hints are visible
- Persistent - Hints stay visible until explicitly dismissed
- Independent - Each hint has its own lifecycle, no sequence required
- Subtle - Pulsing hotspots attract attention without being intrusive
Use hints for:
- New feature announcements
- Contextual help on complex UI elements
- Onboarding nudges that don't require immediate action
- Feature discovery for power users
Use tours instead when:
- You need a sequential, guided walkthrough
- Steps depend on each other
- You want focused, modal-like attention
Installation
pnpm add @tour-kit/hintsnpm install @tour-kit/hintsyarn add @tour-kit/hintsQuick Start
import { HintsProvider, Hint } from '@tour-kit/hints';
function App() {
return (
<HintsProvider>
{/* Add hints to any element */}
<Hint
id="new-feature"
target="#export-button"
content="New! Export your data to CSV or PDF"
/>
<button id="export-button">Export</button>
</HintsProvider>
);
}Architecture
The hints package uses a simple provider/consumer pattern:
HintsProvider
├── Context (state management)
│ ├── hints Map<id, HintState>
│ └── activeHint (only one open at a time)
├── Hint Components
│ ├── HintHotspot (pulsing indicator)
│ └── HintTooltip (floating content)
└── Hooks
├── useHints() (access all hints)
└── useHint(id) (access single hint)State Management
- In-memory state - Hint state is managed via React context with
useReducer - Single active hint - Only one hint tooltip can be open at a time
- Automatic registration - Hints register themselves on mount
- Lifecycle events - Callbacks for show, hide, dismiss actions
Key Concepts
| Concept | Description |
|---|---|
| Hotspot | The pulsing indicator positioned near the target element |
| Tooltip | The floating content that appears when hotspot is clicked |
| Hide | Temporarily close the tooltip (can reopen) |
| Dismiss | Permanently hide the hint (won't show again) |
| Reset | Clear dismissed state (hint can show again) |
Features
Styling Variants
Built-in CVA variants for easy customization:
<Hint
id="hint"
target="#element"
content="..."
size="lg" // 'sm' | 'default' | 'lg'
color="success" // 'default' | 'secondary' | 'destructive' | 'success' | 'warning'
/>Positioning
Hotspots can be positioned at any corner or center:
<Hint position="top-left" />
<Hint position="top-right" /> {/* default */}
<Hint position="bottom-left" />
<Hint position="bottom-right" />
<Hint position="center" />Tooltips use floating-ui for smart positioning with collision detection.
Programmatic Control
Full control via hooks:
const { show, hide, dismiss, reset, isOpen, isDismissed } = useHint('my-hint');
const { hints, showHint, resetAllHints } = useHints();Headless Mode
Build completely custom UIs with headless components:
import { HintHeadless } from '@tour-kit/hints/headless';
<HintHeadless
id="custom"
target="#element"
render={({ isOpen, show, hide, targetRect }) => (
// Your custom UI
)}
/>Bundle Size
| Package | Gzipped |
|---|---|
| @tour-kit/hints | < 5KB |
Package Contents
Components
Hint, HintHotspot, HintTooltip - Pre-styled components with variants
Hooks
useHints, useHint - Programmatic control and state access
Persistence
Dismiss patterns and cross-session storage strategies
Headless
Build custom hint UI with render props
Complete Example
import { HintsProvider, Hint, useHint, useHints } from '@tour-kit/hints';
function App() {
return (
<HintsProvider>
{/* Feature announcement (persistent) */}
<Hint
id="new-dashboard"
target="#dashboard-link"
content="Check out the redesigned dashboard!"
color="success"
persist={true}
/>
{/* Contextual help (can reopen) */}
<Hint
id="filter-help"
target="#filter-button"
content="Use filters to narrow results"
size="sm"
/>
<Dashboard />
<HintControls />
</HintsProvider>
);
}
function HintControls() {
const { resetAllHints } = useHints();
const dashboard = useHint('new-dashboard');
return (
<div>
{dashboard.isDismissed && (
<button onClick={dashboard.reset}>
Show dashboard hint again
</button>
)}
<button onClick={resetAllHints}>Reset all hints</button>
</div>
);
}Accessibility
All hint components are built with accessibility in mind:
- ARIA attributes - Proper roles, labels, and expanded states
- Keyboard support - Escape to dismiss, Tab navigation
- Focus management - Focus rings on keyboard interaction
- Reduced motion - Pulse animation respects
prefers-reduced-motion
The pulsing animation is automatically disabled for users who prefer reduced motion.
Related
- Tours - For sequential, guided walkthroughs
- @tour-kit/core - Shared utilities used by hints