Introduction
Components
- Accordion
- Action Sheet
- Alert
- Audio Player
- Audio Recorder
- Audio Waveform
- Avatar
- Badge
- BottomSheet
- Button
- Camera
- Camera Preview
- Card
- Carousel
- Checkbox
- Collapsible
- Color Picker
- Combobox
- Date Picker
- File Picker
- Gallery
- Hello Wave
- Icon
- Image
- Input
- Input OTP
- Link
- MediaPicker
- Mode Toggle
- Onboarding
- ParallaxScrollView
- Picker
- Popover
- Progress
- Radio
- ScrollView
- SearchBar
- Separator
- Share
- Sheet
- Skeleton
- Spinner
- Switch
- Table
- Tabs
- Text
- Toast
- Toggle
- Video
- View
Charts
import { ParallaxScrollView } from '@/components/ui/parallax-scrollview';
import { Text } from '@/components/ui/text';
import { View } from '@/components/ui/view';
import { Image } from 'expo-image';
import React from 'react';
export function ParallaxScrollViewDemo() {
return (
<ParallaxScrollView
headerHeight={460}
headerImage={
<Image
source={{
uri: 'https://images.unsplash.com/photo-1637858868799-7f26a0640eb6?q=80&w=2960&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
}}
style={{ width: '100%', height: '100%' }}
contentFit='cover'
/>
}
>
<View style={{ gap: 16 }}>
<Text variant='heading'>Parallax Scroll View</Text>
<Text>
This is a basic example of a parallax scroll view. The header image
moves at a different speed than the content as you scroll, creating a
beautiful parallax effect.
</Text>
<Text>
Scroll up and down to see the parallax animation in action. The header
will transform and scale based on your scroll position.
</Text>
<Text>
You can also try pulling down (over-scrolling) to see the header scale
up beyond its normal size.
</Text>
</View>
</ParallaxScrollView>
);
}
Installation
pnpm dlx bna-ui add parallax-scrollview
Usage
import { ParallaxScrollView } from '@/components/ui/parallax-scrollview';
import { Image } from 'expo-image';
<ParallaxScrollView
headerHeight={300}
headerImage={
<Image
source={{ uri: 'https://example.com/header-image.jpg' }}
style={{ width: '100%', height: '100%' }}
contentFit='cover'
/>
}
>
<Text>Your scrollable content goes here...</Text>
</ParallaxScrollView>
Examples
Default
import { ParallaxScrollView } from '@/components/ui/parallax-scrollview';
import { Text } from '@/components/ui/text';
import { View } from '@/components/ui/view';
import { Image } from 'expo-image';
import React from 'react';
export function ParallaxScrollViewDemo() {
return (
<ParallaxScrollView
headerHeight={460}
headerImage={
<Image
source={{
uri: 'https://images.unsplash.com/photo-1637858868799-7f26a0640eb6?q=80&w=2960&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
}}
style={{ width: '100%', height: '100%' }}
contentFit='cover'
/>
}
>
<View style={{ gap: 16 }}>
<Text variant='heading'>Parallax Scroll View</Text>
<Text>
This is a basic example of a parallax scroll view. The header image
moves at a different speed than the content as you scroll, creating a
beautiful parallax effect.
</Text>
<Text>
Scroll up and down to see the parallax animation in action. The header
will transform and scale based on your scroll position.
</Text>
<Text>
You can also try pulling down (over-scrolling) to see the header scale
up beyond its normal size.
</Text>
</View>
</ParallaxScrollView>
);
}
Custom Header Height
import { ParallaxScrollView } from '@/components/ui/parallax-scrollview';
import { Text } from '@/components/ui/text';
import { View } from '@/components/ui/view';
import { Image } from 'expo-image';
import React from 'react';
export function ParallaxScrollViewCustomHeight() {
return (
<ParallaxScrollView
headerHeight={500}
headerImage={
<Image
source={{
uri: 'https://images.unsplash.com/photo-1644190022446-04b99df7259a?q=80&w=2012&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
}}
style={{ width: '100%', height: '100%' }}
contentFit='cover'
/>
}
>
<View style={{ gap: 16 }}>
<Text variant='heading'>Custom Header Height</Text>
<Text>
This example demonstrates a taller header (500px) that provides more
visual impact and space for the parallax effect.
</Text>
<Text>
Larger headers work great for hero sections, profile pages, or any
screen where you want to make a strong visual impression.
</Text>
<Text>
The parallax animation remains smooth regardless of the header size,
automatically adjusting the transformation values based on the
specified height.
</Text>
<Text>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
</Text>
</View>
</ParallaxScrollView>
);
}
Gradient Header
import { ParallaxScrollView } from '@/components/ui/parallax-scrollview';
import { Text } from '@/components/ui/text';
import { View } from '@/components/ui/view';
import { Image } from 'expo-image';
import { LinearGradient } from 'expo-linear-gradient';
import React from 'react';
export function ParallaxScrollViewGradient() {
return (
<ParallaxScrollView
headerHeight={300}
headerImage={
<View style={{ position: 'relative', width: '100%', height: '100%' }}>
<Image
source={{
uri: 'https://images.unsplash.com/photo-1575737698350-52e966f924d4?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
}}
style={{ width: '100%', height: '100%' }}
contentFit='cover'
/>
<LinearGradient
colors={['transparent', 'black']}
style={{
position: 'absolute',
bottom: 0,
left: 0,
right: 0,
height: '50%',
}}
/>
<View
style={{
position: 'absolute',
bottom: 20,
left: 20,
right: 20,
}}
>
<Text
style={{
color: 'white',
fontSize: 24,
fontWeight: 'bold',
textShadowColor: 'rgba(0,0,0,0.5)',
textShadowOffset: { width: 1, height: 1 },
textShadowRadius: 2,
}}
>
Scenic Mountain View
</Text>
</View>
</View>
}
>
<View style={{ gap: 16 }}>
<Text variant='heading'>Gradient Overlay Header</Text>
<Text>
This example shows how to add a gradient overlay to your header image,
which is perfect for ensuring text readability over images.
</Text>
<Text>
The gradient creates a smooth transition from the image to a darker
overlay at the bottom, where you can place text or other UI elements.
</Text>
<Text>
This technique is commonly used in hero sections, article headers, and
profile screens where you need to overlay content on images.
</Text>
<Text>
The parallax effect works seamlessly with gradient overlays and
maintains smooth performance even with multiple layers.
</Text>
</View>
</ParallaxScrollView>
);
}
Profile Screen
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import { Badge } from '@/components/ui/badge';
import { ParallaxScrollView } from '@/components/ui/parallax-scrollview';
import { Text } from '@/components/ui/text';
import { View } from '@/components/ui/view';
import { Image } from 'expo-image';
import { LinearGradient } from 'expo-linear-gradient';
import React from 'react';
export function ParallaxScrollViewProfile() {
return (
<ParallaxScrollView
headerHeight={320}
headerImage={
<View style={{ position: 'relative', width: '100%', height: '100%' }}>
<Image
source={{
uri: 'https://images.unsplash.com/photo-1637858868799-7f26a0640eb6?q=80&w=2960&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
}}
style={{ width: '100%', height: '100%' }}
contentFit='cover'
/>
<LinearGradient
colors={['transparent', 'black']}
style={{
position: 'absolute',
bottom: 0,
left: 0,
right: 0,
height: '80%',
}}
/>
<View
style={{
position: 'absolute',
bottom: 20,
left: 0,
right: 0,
alignItems: 'center',
gap: 12,
}}
>
<Avatar size={90}>
<AvatarImage
source={{
uri: 'https://avatars.githubusercontent.com/u/99088394?v=4',
}}
/>
<AvatarFallback>JD</AvatarFallback>
</Avatar>
<View style={{ alignItems: 'center' }}>
<Text
style={{
color: 'white',
fontSize: 24,
fontWeight: 'bold',
textShadowColor: 'rgba(0,0,0,0.5)',
textShadowOffset: { width: 1, height: 1 },
textShadowRadius: 2,
}}
>
John Doe
</Text>
<Text
style={{
color: '#e0e0e0',
fontSize: 16,
textShadowColor: 'rgba(0,0,0,0.5)',
textShadowOffset: { width: 1, height: 1 },
textShadowRadius: 2,
}}
>
Software Engineer
</Text>
</View>
</View>
</View>
}
>
<View style={{ gap: 20 }}>
<View style={{ gap: 8 }}>
<Text variant='title'>About</Text>
<Text>
Passionate software engineer with 5+ years of experience in mobile
and web development. Specialized in React Native, TypeScript, and
modern UI frameworks.
</Text>
</View>
<View style={{ gap: 8 }}>
<Text variant='title'>Skills</Text>
<View
style={{
flexDirection: 'row',
flexWrap: 'wrap',
gap: 8,
}}
>
{[
'React Native',
'TypeScript',
'Node.js',
'GraphQL',
'MongoDB',
].map((skill) => (
<Badge variant='success' key={skill}>
{skill}
</Badge>
))}
</View>
</View>
<View style={{ gap: 8 }}>
<Text variant='title'>Experience</Text>
<View style={{ gap: 12 }}>
<View>
<Text variant='subtitle'>Senior Mobile Developer</Text>
<Text variant='caption'>Tech Corp • 2022 - Present</Text>
<Text style={{ marginTop: 4 }}>
Leading mobile development team and architecting scalable React
Native applications.
</Text>
</View>
<View>
<Text variant='subtitle'>Frontend Developer</Text>
<Text variant='caption'>StartupXYZ • 2020 - 2022</Text>
<Text style={{ marginTop: 4 }}>
Built responsive web applications using React and modern
frontend technologies.
</Text>
</View>
</View>
</View>
<View style={{ gap: 8 }}>
<Text variant='title'>Contact</Text>
<Text>📧 john.doe@example.com</Text>
<Text>🌐 johndoe.dev</Text>
<Text>📱 LinkedIn: @johndoe</Text>
</View>
</View>
</ParallaxScrollView>
);
}
Article View
import { ParallaxScrollView } from '@/components/ui/parallax-scrollview';
import { Text } from '@/components/ui/text';
import { View } from '@/components/ui/view';
import { Image } from 'expo-image';
import { LinearGradient } from 'expo-linear-gradient';
import React from 'react';
export function ParallaxScrollViewArticle() {
return (
<ParallaxScrollView
headerHeight={280}
headerImage={
<View style={{ position: 'relative', width: '100%', height: '100%' }}>
<Image
source={{
uri: 'https://images.unsplash.com/photo-1486312338219-ce68d2c6f44d?w=800&h=600&fit=crop',
}}
style={{ width: '100%', height: '100%' }}
contentFit='cover'
/>
<LinearGradient
colors={['transparent', 'rgba(0,0,0,0.7)']}
style={{
position: 'absolute',
bottom: 0,
left: 0,
right: 0,
height: '60%',
}}
/>
<View
style={{
position: 'absolute',
bottom: 20,
left: 20,
right: 20,
}}
>
<View
style={{
backgroundColor: 'green',
paddingHorizontal: 8,
paddingVertical: 4,
borderRadius: 4,
alignSelf: 'flex-start',
marginBottom: 8,
}}
>
<Text style={{ color: 'white', fontSize: 12, fontWeight: '600' }}>
TECHNOLOGY
</Text>
</View>
<Text
style={{
color: 'white',
fontSize: 24,
fontWeight: 'bold',
lineHeight: 32,
textShadowColor: 'rgba(0,0,0,0.5)',
textShadowOffset: { width: 1, height: 1 },
textShadowRadius: 2,
}}
>
The Future of Mobile Development
</Text>
<Text
style={{
color: '#e0e0e0',
fontSize: 14,
marginTop: 8,
textShadowColor: 'rgba(0,0,0,0.5)',
textShadowOffset: { width: 1, height: 1 },
textShadowRadius: 2,
}}
>
Published on March 15, 2024 • 8 min read
</Text>
</View>
</View>
}
>
<View style={{ gap: 16 }}>
<Text variant='caption' style={{ fontSize: 18, lineHeight: 28 }}>
Mobile development has evolved dramatically over the past decade, with
new frameworks, tools, and paradigms emerging to meet the ever-growing
demands of users and businesses alike.
</Text>
<Text variant='caption'>
React Native has established itself as a leading cross-platform
solution, enabling developers to write once and deploy everywhere. The
framework's component-based architecture and hot reloading
capabilities have revolutionized the development experience.
</Text>
<View style={{ gap: 8 }}>
<Text variant='title'>Key Trends in 2024</Text>
<Text variant='caption'>
• AI-powered development tools and code generation
</Text>
<Text variant='caption'>
• Enhanced performance optimization techniques
</Text>
<Text variant='caption'>
• Better cross-platform native module integration
</Text>
<Text variant='caption'>
• Improved debugging and testing frameworks
</Text>
</View>
<View
style={{
padding: 16,
borderRadius: 8,
borderLeftWidth: 4,
borderLeftColor: '#3b82f6',
}}
>
<Text style={{ fontSize: 16, lineHeight: 24, fontStyle: 'italic' }}>
"The best mobile apps are those that feel native to each platform
while maintaining a consistent user experience across devices."
</Text>
</View>
<Text variant='caption'>
Performance optimization remains a critical consideration. Modern apps
need to handle complex animations, large datasets, and real-time
updates while maintaining smooth 60fps interactions.
</Text>
<View style={{ gap: 8 }}>
<Text variant='title'>Looking Ahead</Text>
<Text variant='caption'>
The future of mobile development is bright, with emerging
technologies like AR/VR integration, improved offline capabilities,
and seamless cloud integration opening new possibilities for
developers and users alike.
</Text>
</View>
<View
style={{
borderTopWidth: 0.5,
borderTopColor: '#e5e7eb',
paddingTop: 16,
marginTop: 16,
}}
>
<View
style={{
flexDirection: 'row',
alignItems: 'center',
gap: 12,
}}
>
<View
style={{
width: 40,
height: 40,
borderRadius: 20,
backgroundColor: '#3b82f6',
alignItems: 'center',
justifyContent: 'center',
}}
>
<Text style={{ color: 'white', fontWeight: 'bold' }}>JD</Text>
</View>
<View>
<Text style={{ fontWeight: '600' }}>John Developer</Text>
<Text style={{ color: '#6b7280', fontSize: 14 }}>
Senior Mobile Engineer
</Text>
</View>
</View>
</View>
</View>
</ParallaxScrollView>
);
}
Product Gallery
import { Button } from '@/components/ui/button';
import { ParallaxScrollView } from '@/components/ui/parallax-scrollview';
import { Text } from '@/components/ui/text';
import { View } from '@/components/ui/view';
import { Image } from 'expo-image';
import React from 'react';
export function ParallaxScrollViewProduct() {
return (
<ParallaxScrollView
headerHeight={350}
headerImage={
<Image
source={{
uri: 'https://images.unsplash.com/photo-1542291026-7eec264c27ff?w=800&h=600&fit=crop',
}}
style={{ width: '100%', height: '100%' }}
contentFit='cover'
/>
}
>
<View style={{ gap: 20 }}>
<View style={{ gap: 8 }}>
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'flex-start',
}}
>
<View style={{ flex: 1 }}>
<Text variant='heading'>Running Shoes</Text>
<Text variant='caption' style={{ marginTop: 4 }}>
Nike Air Zoom Series
</Text>
</View>
<Text
style={{
fontSize: 24,
fontWeight: 'bold',
color: '#dc2626',
}}
>
$159.99
</Text>
</View>
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
<View style={{ flexDirection: 'row', gap: 2 }}>
{[1, 2, 3, 4, 5].map((star) => (
<Text key={star} style={{ color: '#fbbf24', fontSize: 16 }}>
★
</Text>
))}
</View>
<Text variant='caption'>4.8 (2.1k reviews)</Text>
</View>
</View>
<View style={{ gap: 8 }}>
<Text variant='title'>Description</Text>
<Text variant='caption' style={{ fontSize: 16, lineHeight: 24 }}>
Experience ultimate comfort and performance with these premium
running shoes. Featuring advanced cushioning technology and
breathable mesh construction for all-day comfort.
</Text>
</View>
<View style={{ gap: 12 }}>
<Text variant='title'>Available Sizes</Text>
<View
style={{
flexDirection: 'row',
flexWrap: 'wrap',
gap: 8,
}}
>
{['7', '7.5', '8', '8.5', '9', '9.5', '10', '10.5', '11'].map(
(size) => (
<View
key={size}
style={{
borderWidth: 1,
borderColor: '#d1d5db',
paddingHorizontal: 16,
paddingVertical: 8,
borderRadius: 8,
minWidth: 50,
alignItems: 'center',
}}
>
<Text style={{ fontWeight: '500' }}>US {size}</Text>
</View>
)
)}
</View>
</View>
<View style={{ gap: 12 }}>
<Text variant='title'>Color Options</Text>
<View style={{ flexDirection: 'row', gap: 12 }}>
<View
style={{
width: 40,
height: 40,
borderRadius: 20,
backgroundColor: '#1f2937',
borderWidth: 2,
borderColor: '#3b82f6',
}}
/>
<View
style={{
width: 40,
height: 40,
borderRadius: 20,
backgroundColor: '#ffffff',
borderWidth: 1,
borderColor: '#d1d5db',
}}
/>
<View
style={{
width: 40,
height: 40,
borderRadius: 20,
backgroundColor: '#dc2626',
}}
/>
<View
style={{
width: 40,
height: 40,
borderRadius: 20,
backgroundColor: '#2563eb',
}}
/>
</View>
</View>
<View style={{ gap: 8 }}>
<Text variant='title'>Features</Text>
<View style={{ gap: 8 }}>
<View
style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}
>
<Text style={{ color: '#10b981' }}>✓</Text>
<Text variant='caption'>Lightweight design for all-day wear</Text>
</View>
<View
style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}
>
<Text style={{ color: '#10b981' }}>✓</Text>
<Text variant='caption'>Enhanced arch support</Text>
</View>
</View>
</View>
<View
style={{
borderRadius: 8,
gap: 12,
}}
>
<Text variant='title'>Shipping & Returns</Text>
<Text style={{ fontSize: 14 }}>
• Free shipping on orders over $100
</Text>
<Text style={{ fontSize: 14 }}>• 30-day return policy</Text>
<Text style={{ fontSize: 14 }}>• 1-year manufacturer warranty</Text>
</View>
<View style={{ gap: 12, marginTop: 8 }}>
<Button variant='success'>Add to Cart</Button>
<Button variant='destructive'>Add to Wishlist</Button>
</View>
</View>
</ParallaxScrollView>
);
}
API Reference
ParallaxScrollView
The main component that provides parallax scrolling functionality.
Prop | Type | Default | Description |
---|---|---|---|
children | ReactNode | - | The scrollable content below the header. |
headerHeight | number | 250 | The height of the parallax header in pixels. |
headerImage | ReactElement | - | The header content (image, video, or custom element). |
Animation Behavior
The ParallaxScrollView component provides smooth parallax animations:
- Transform: Header moves at different speeds during scroll
- Scale: Header scales up when pulled down (over-scroll)
- Performance: Uses native driver for 60fps animations
- Responsive: Adapts to different screen sizes and orientations
Scroll Effects
- Pull Down: Header scales up to 2x when over-scrolling
- Scroll Up: Header translates upward at 0.5x scroll speed
- Scale Down: Header maintains aspect ratio during transformations
Accessibility
The ParallaxScrollView component follows accessibility best practices:
- Maintains scroll accessibility for screen readers
- Preserves focus management during animations
- Supports reduced motion preferences
- Compatible with VoiceOver and TalkBack
Performance Tips
- Use optimized images with appropriate resolutions
- Consider lazy loading for heavy content
- Use
scrollEventThrottle={16}
for smooth animations - Implement proper image caching strategies
Common Use Cases
- Profile screens with hero images
- Article headers with featured images
- Product detail pages
- Landing pages with hero sections
- Photo gallery headers
- Settings pages with branded headers