Package Exports
- gabay
- gabay/dist/index.esm.js
- gabay/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (gabay) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Gabay
A lightweight React library for creating beautiful user onboarding experiences. Only 10.6 KB gzipped with zero runtime dependencies.
Gabay (pronounced "gah-BAY") means "guide" or "tutor" in Filipino. This library helps you guide your users through your application with elegant, accessible tours.
✨ Features
- 🎯 Ultra-lightweight - 10.6 KB gzipped, zero dependencies
- ⚛️ Dual API - Declarative component or imperative hooks
- 📱 Responsive - Auto-positioning, mobile-friendly
- ♿ Accessible - ARIA attributes, keyboard navigation, focus management
- 🎭 TypeScript - Full type safety
- 🎨 Minimalist - Clean design, easy to customize
📦 Installation
npm install gabay
# or
yarn add gabay
# or
pnpm add gabayDon't forget to import the CSS:
import "gabay/dist/index.esm.css";🚀 Quick Start
Declarative API (Recommended)
import { Gabay } from "gabay";
import "gabay/dist/index.esm.css";
function App() {
const config = {
steps: [
{
id: "welcome",
target: "#welcome-button",
title: "Welcome!",
content: "Click here to get started.",
position: "bottom",
},
{
id: "features",
target: "#features",
content: "Check out our features.",
},
],
startOnMount: true,
onComplete: () => console.log("Tour completed!"),
};
return (
<Gabay config={config}>
<div>
<button id="welcome-button">Get Started</button>
<div id="features">Features</div>
</div>
</Gabay>
);
}Imperative API (Programmatic Control)
import { GabayProvider, useGabay } from "gabay";
import "gabay/dist/index.esm.css";
function AppContent() {
const { start, next, previous, isActive, currentStep } = useGabay();
return (
<div>
<button onClick={start}>Start Tour</button>
{isActive && (
<div>
<p>{currentStep?.title}</p>
<button onClick={previous}>Previous</button>
<button onClick={next}>Next</button>
</div>
)}
</div>
);
}
function App() {
return (
<GabayProvider
config={{
steps: [
{ id: "1", target: "#btn1", content: "First step" },
{ id: "2", target: "#btn2", content: "Second step" },
],
}}
>
<AppContent />
</GabayProvider>
);
}📚 API Reference
<Gabay> Component
Wrapper component for declarative gabay.
Props:
interface GabayProps {
config: {
steps: Step[];
onComplete?: () => void;
onSkip?: () => void;
startOnMount?: boolean; // Auto-start on mount
};
children: ReactNode;
}<GabayProvider> Component
Context provider for programmatic control via hooks.
Props: Same as Gabay config prop.
useGabay() Hook
Returns gabay state and control methods:
{
steps: Step[];
currentStepIndex: number;
currentStep: Step | null;
isActive: boolean;
isFirstStep: boolean;
isLastStep: boolean;
start: () => void;
next: () => void;
previous: () => void;
skip: () => void;
complete: () => void;
goToStep: (stepId: string) => void;
}useStep(stepId: string) Hook
Returns step-specific state:
{
step: Step | null;
isActive: boolean;
stepIndex: number;
isCurrentStep: boolean;
goTo: () => void;
}Step Type
interface Step {
id: string; // Required: unique identifier
target?: string | HTMLElement; // CSS selector or element
title?: string; // Optional tooltip title
content: string; // Required: tooltip content
position?: "top" | "bottom" | "left" | "right" | "center"; // Auto if omitted
onNext?: () => void; // Called before moving to next step
onPrevious?: () => void; // Called before moving to previous step
}⌨️ Keyboard Navigation
Escape- Skip/close tourArrow Right/Arrow Down- Next stepArrow Left/Arrow Up- Previous step
🎨 Step Positions
'top'- Tooltip above target'bottom'- Tooltip below target (default)'left'- Tooltip to the left'right'- Tooltip to the right'center'- Tooltip centered on target
If omitted, the library auto-detects the best position based on viewport space.
💡 Examples
Step with Callback
{
id: 'step-1',
target: '#button',
content: 'Click this button',
onNext: () => {
// Custom logic before next step
console.log('Moving forward');
},
}Dynamic Target
{
id: 'dynamic',
target: document.querySelector('#dynamic-element'),
content: 'This targets a specific element',
}No Target (Center Position)
{
id: 'welcome',
content: 'Welcome to our app!',
position: 'center', // Centers on viewport
}🎨 Styling
The library includes a minimalist gray-white theme. Styles are scoped with CSS Modules and included in the bundle.
To customize, override CSS variables or provide your own styles targeting the component classes.
🌐 Browser Support
Modern browsers with ES2022 support:
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
📖 More Examples
Check out the demo app for complete examples including:
- Automated tours
- Interactive mode
- Custom controls
- Real-world dashboard example
🤝 Contributing
Contributions welcome! Please feel free to submit a Pull Request.
📄 License
MIT © git-yehoshua
Made with ❤️ for the React community