Package Exports
- react-scroll-narrator
- react-scroll-narrator/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 (react-scroll-narrator) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
React Scroll Narrator
A powerful React component for creating Apple-style scroll-driven storytelling experiences with smooth animations, parallax effects, and interactive navigation.

🚀 What's New
- Programmatic Navigation: Direct API access with
scrollToStep()method - Enhanced Progress Indicators: Click to navigate functionality
- Improved Performance: Dual detection system with scroll listeners and IntersectionObserver
- Better Animation Triggers: Content appears immediately when sections become active
- Full Viewport Sections: Each NarrationStep takes full screen height (100vh)
✨ Features
- 🎭 Multiple Animation Types: Fade, slide, scale, reveal, parallax, and custom animations
- 📱 Touch & Mobile Optimized: Swipe gestures and touch navigation
- ⌨️ Keyboard Navigation: Full keyboard support with arrow keys and number shortcuts
- 🎨 Parallax Backgrounds: Smooth parallax scrolling effects
- 📍 Progress Indicators: Interactive dots, bars, and minimal progress displays with click navigation
- ♿ Accessibility Ready: Screen reader support and ARIA attributes
- ⚡ High Performance: Optimized with IntersectionObserver API and scroll-based detection
- 🔧 Fully Customizable: Extensive props for styling and behavior
- 🎯 TypeScript Support: Complete type definitions included
- 🎪 Programmatic Control: Direct API access for custom navigation and control
🚀 Installation
npm install react-scroll-narratorPeer Dependencies
npm install react react-dom framer-motion clsx📖 Quick Start
import { ScrollNarrator, NarrationStep, ProgressIndicator, ScrollNarratorRef } from "react-scroll-narrator";
import { useState, useRef } from "react";
export default function MyApp() {
const [currentStep, setCurrentStep] = useState(0);
const scrollNarratorRef = useRef<ScrollNarratorRef>(null);
const handleStepClick = (stepIndex) => {
scrollNarratorRef.current?.scrollToStep(stepIndex);
};
return (
<div className="relative">
{/* Progress Indicator */}
<ProgressIndicator
total={3}
current={currentStep}
style="dots"
position="right"
onStepClick={handleStepClick}
/>
<ScrollNarrator
ref={scrollNarratorRef}
animation="fade"
onStepChange={setCurrentStep}
keyboardNavigation={true}
touchNavigation={true}
>
<NarrationStep>
<h1>Welcome to Scroll Narrator! 🚀</h1>
<p>Your scroll-driven storytelling starts here.</p>
</NarrationStep>
<NarrationStep animation="slideUp">
<div className="product-showcase">
<img src="/product.png" alt="Amazing Product" />
<h2>Incredible Features</h2>
<p>Experience the magic of smooth scroll animations.</p>
</div>
</NarrationStep>
<NarrationStep animation="reveal">
<div className="cta-section">
<h2>Get Started Today</h2>
<button>Learn More</button>
</div>
</NarrationStep>
</ScrollNarrator>
</div>
);
}🎛️ API Reference
ScrollNarrator
The main container component that manages scroll behavior and step transitions.
const scrollNarratorRef = useRef<ScrollNarratorRef>(null);
// Programmatic navigation
scrollNarratorRef.current?.scrollToStep(2);
<ScrollNarrator
ref={scrollNarratorRef}
animation="fade"
onStepChange={(index) => console.log(index)}
keyboardNavigation={true}
touchNavigation={true}
parallax={true}
parallaxSpeed={0.5}
className="my-custom-class"
>
{/* NarrationStep components */}
</ScrollNarrator>Props
| Prop | Type | Default | Description |
|---|---|---|---|
animation |
AnimationType |
"fade" |
Default animation for all steps |
onStepChange |
(index: number, stepId?: string) => void |
- | Callback when step becomes active |
sticky |
boolean |
true |
Whether steps are sticky scroll |
parallax |
boolean |
false |
Enable parallax backgrounds |
parallaxSpeed |
number |
0.5 |
Parallax scroll speed multiplier |
keyboardNavigation |
boolean |
true |
Enable keyboard navigation |
touchNavigation |
boolean |
true |
Enable touch/swipe navigation |
className |
string |
- | Custom CSS class |
style |
CSSProperties |
- | Custom inline styles |
Ref Methods
| Method | Signature | Description |
|---|---|---|
scrollToStep |
(stepIndex: number) => void |
Programmatically scroll to a specific step |
TypeScript Types
import type {
ScrollNarratorProps,
NarrationStepProps,
AnimationType,
ProgressIndicatorProps,
ScrollNarratorRef
} from "react-scroll-narrator";NarrationStep
Individual step component that contains your content and handles animations.
<NarrationStep
id="unique-step-id"
animation="slideUp"
backgroundImage="/hero-bg.jpg"
backgroundColor="#000"
className="custom-step-class"
>
<h1>Your Content Here</h1>
</NarrationStep>Props
| Prop | Type | Default | Description |
|---|---|---|---|
id |
string |
auto |
Unique step identifier |
animation |
AnimationType |
inherit |
Override animation for this step |
backgroundImage |
string |
- | Background image URL |
backgroundColor |
string |
- | Background color |
className |
string |
- | Custom CSS class |
style |
CSSProperties |
- | Custom inline styles |
ProgressIndicator
Visual indicator showing current progress through the narrative.
<ProgressIndicator
total={5}
current={2}
style="dots"
position="right"
onStepClick={(index) => console.log(index)}
size="lg"
showNumbers={true}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
total |
number |
- | Total number of steps |
current |
number |
- | Current active step index |
style |
"dots" | "bar" | "minimal" |
"dots" |
Indicator style |
position |
"top" | "bottom" | "left" | "right" |
"right" |
Position on screen |
onStepClick |
(index: number) => void |
- | Click handler for navigation |
showNumbers |
boolean |
false |
Show step numbers |
size |
"sm" | "md" | "lg" |
"md" |
Indicator size |
className |
string |
- | Custom CSS class |
🎨 Animation Types
Choose from these built-in animation types:
"fade"- Simple opacity transition"slide"- Slide in from right"slideUp"- Slide up from bottom"slideDown"- Slide down from top"slideLeft"- Slide in from right"slideRight"- Slide in from left"scale"- Scale in with opacity"scaleFade"- Gentle scale and fade"reveal"- Clip-path reveal effect"parallax"- Subtle parallax movement"none"- No animation
🎯 Advanced Examples
With Progress Indicator
import { ScrollNarrator, NarrationStep, ProgressIndicator, ScrollNarratorRef } from "react-scroll-narrator";
import { useState, useRef } from "react";
function App() {
const [currentStep, setCurrentStep] = useState(0);
const scrollNarratorRef = useRef<ScrollNarratorRef>(null);
const handleStepClick = (stepIndex: number) => {
scrollNarratorRef.current?.scrollToStep(stepIndex);
};
return (
<div className="relative">
<ProgressIndicator
total={3}
current={currentStep}
style="dots"
position="right"
onStepClick={handleStepClick}
size="lg"
/>
<ScrollNarrator
ref={scrollNarratorRef}
onStepChange={setCurrentStep}
keyboardNavigation={true}
touchNavigation={true}
>
<NarrationStep>
<h1>Step 1</h1>
<p>Scroll or click the dots to navigate</p>
</NarrationStep>
<NarrationStep animation="slideUp">
<h1>Step 2</h1>
<p>Smooth animations and interactions</p>
</NarrationStep>
<NarrationStep animation="reveal">
<h1>Step 3</h1>
<p>Beautiful storytelling experiences</p>
</NarrationStep>
</ScrollNarrator>
</div>
);
}With Parallax Backgrounds
<ScrollNarrator
height="100vh"
parallax={true}
parallaxSpeed={0.3}
>
<NarrationStep backgroundImage="/mountain-bg.jpg">
<h1>Mountain View</h1>
</NarrationStep>
<NarrationStep backgroundImage="/ocean-bg.jpg">
<h1>Ocean Scene</h1>
</NarrationStep>
</ScrollNarrator>Custom Animations with Framer Motion
import { motion } from "framer-motion";
<NarrationStep animation="none">
<motion.div
initial={{ x: -100, opacity: 0 }}
animate={{ x: 0, opacity: 1 }}
transition={{ duration: 0.8, ease: "easeOut" }}
>
<h1>Custom Animation</h1>
</motion.div>
</NarrationStep>🎮 Controls
Keyboard Navigation
↑/↓orPage Up/Down- Navigate between stepsHome/End- Jump to first/last step1-9- Jump to specific step number
Touch Navigation
- Swipe Up/Down - Navigate between steps on mobile devices
- Touch optimized for smooth scrolling experience
🎨 Styling
The component comes with minimal default styles. You can customize everything with CSS:
/* Custom step styles */
.narration-step {
/* Your custom styles */
}
/* Container styles */
.scroll-narrator-container {
/* Container modifications */
}
/* Progress indicator customization */
.progress-indicator {
/* Custom progress styles */
}🔧 TypeScript Support
Full TypeScript support with complete type definitions:
import type {
ScrollNarratorProps,
NarrationStepProps,
AnimationType,
ProgressIndicatorProps
} from "react-scroll-narrator";🌟 Use Cases
- Product Showcases - Apple-style product reveals
- Storytelling Websites - Long-form narratives with smooth transitions
- Portfolio Sites - Creative showcases with scroll interactions
- Marketing Landing Pages - Engaging user experiences
- Interactive Presentations - Scroll-based slide decks
- Brand Stories - Cinematic storytelling experiences
📱 Browser Support
- Chrome 58+
- Firefox 55+
- Safari 11+
- Edge 79+
- iOS Safari 11+
- Android Chrome 58+
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
- Inspired by Apple's product pages and modern web storytelling
- Built with Framer Motion for animations
- Uses IntersectionObserver API for performance
Made with ❤️ for creating beautiful scroll experiences