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 { ShareButton } from '@/components/ui/share';
import React from 'react';
export function ShareDemo() {
return (
<ShareButton
content={{
message: 'Check out this amazing app!',
url: 'https://example.com',
title: 'Amazing App',
}}
onShareSuccess={(activityType) => {
console.log('Shared successfully:', activityType);
}}
onShareError={(error) => {
console.error('Share failed:', error);
}}
>
Share
</ShareButton>
);
}
Installation
pnpm dlx bna-ui add share
Usage
import { ShareButton, useShare } from '@/components/ui/share';
<ShareButton
content={{
message: 'Check out this amazing app!',
url: 'https://example.com',
}}
>
Share
</ShareButton>
Examples
Default
import { ShareButton } from '@/components/ui/share';
import React from 'react';
export function ShareDemo() {
return (
<ShareButton
content={{
message: 'Check out this amazing app!',
url: 'https://example.com',
title: 'Amazing App',
}}
onShareSuccess={(activityType) => {
console.log('Shared successfully:', activityType);
}}
onShareError={(error) => {
console.error('Share failed:', error);
}}
>
Share
</ShareButton>
);
}
Share Variants
import { ShareButton } from '@/components/ui/share';
import { View } from '@/components/ui/view';
import React from 'react';
export function ShareVariants() {
const shareContent = {
message: 'Check out this amazing content!',
url: 'https://example.com',
};
return (
<View style={{ flexDirection: 'row', flexWrap: 'wrap', gap: 12 }}>
<ShareButton content={shareContent} variant='default'>
Default
</ShareButton>
<ShareButton content={shareContent} variant='secondary'>
Secondary
</ShareButton>
<ShareButton content={shareContent} variant='outline'>
Outline
</ShareButton>
<ShareButton content={shareContent} variant='ghost'>
Ghost
</ShareButton>
<ShareButton content={shareContent} variant='link'>
Link
</ShareButton>
<ShareButton content={shareContent} variant='destructive'>
Destructive
</ShareButton>
</View>
);
}
Share Sizes
import { ShareButton } from '@/components/ui/share';
import { View } from '@/components/ui/view';
import React from 'react';
export function ShareSizes() {
const shareContent = {
message: 'Check out this amazing content!',
url: 'https://example.com',
};
return (
<View style={{ gap: 12, alignItems: 'center' }}>
<ShareButton content={shareContent} size='sm'>
Small
</ShareButton>
<ShareButton content={shareContent} size='default'>
Default
</ShareButton>
<ShareButton content={shareContent} size='lg'>
Large
</ShareButton>
<ShareButton content={shareContent} size='icon' iconSize={20} />
</View>
);
}
URL Only
import { ShareButton } from '@/components/ui/share';
import { View } from '@/components/ui/view';
import React from 'react';
export function ShareUrlOnly() {
return (
<View style={{ gap: 12 }}>
<ShareButton content={{ url: 'https://github.com' }} variant='outline'>
Share GitHub
</ShareButton>
<ShareButton
content={{ url: 'https://reactnative.dev' }}
variant='secondary'
>
Share React Native Docs
</ShareButton>
<ShareButton content={{ url: 'https://expo.dev' }} variant='ghost'>
Share Expo
</ShareButton>
</View>
);
}
Custom Content
import { ShareButton } from '@/components/ui/share';
import { View } from '@/components/ui/view';
import React from 'react';
export function ShareCustomContent() {
return (
<View style={{ gap: 12 }}>
{/* Rich content with title and subject */}
<ShareButton
content={{
message:
'I found this amazing article about React Native development. You should definitely check it out!',
url: 'https://reactnative.dev/blog',
title: 'React Native Blog',
subject: 'Great React Native Article',
}}
options={{
dialogTitle: 'Share this article',
}}
>
Share Article
</ShareButton>
{/* App promotion */}
<ShareButton
content={{
message:
'๐ Just discovered this incredible mobile app! The UI is amazing and it works perfectly on both iOS and Android. Download it now!',
url: 'https://apps.apple.com/app/example',
title: 'Amazing Mobile App',
subject: 'You need to try this app!',
}}
variant='secondary'
>
Share App
</ShareButton>
{/* Event invitation */}
<ShareButton
content={{
message:
"๐ You're invited to our tech meetup! Join us for an evening of networking, learning, and great discussions about mobile development.",
url: 'https://meetup.com/event/123',
title: 'Tech Meetup Invitation',
subject: 'Join us at the Tech Meetup!',
}}
variant='outline'
>
Share Event
</ShareButton>
</View>
);
}
Icon Only
import { ShareButton } from '@/components/ui/share';
import { View } from '@/components/ui/view';
import React from 'react';
export function ShareIconOnly() {
const shareContent = {
message: 'Check out this amazing content!',
url: 'https://example.com',
};
return (
<View style={{ flexDirection: 'row', gap: 8 }}>
<ShareButton
content={shareContent}
size='icon'
variant='default'
iconSize={18}
/>
<ShareButton
content={shareContent}
size='icon'
variant='secondary'
iconSize={18}
/>
<ShareButton
content={shareContent}
size='icon'
variant='outline'
iconSize={18}
/>
<ShareButton
content={shareContent}
size='icon'
variant='ghost'
iconSize={20}
/>
</View>
);
}
With Callbacks
import { ShareButton } from '@/components/ui/share';
import { Text } from '@/components/ui/text';
import { View } from '@/components/ui/view';
import React, { useState } from 'react';
export function ShareCallbacks() {
const [status, setStatus] = useState<string>('Ready to share');
const [isLoading, setIsLoading] = useState(false);
const handleShareStart = () => {
setStatus('Starting share...');
setIsLoading(true);
};
const handleShareSuccess = (activityType?: string | null) => {
setStatus(
`Shared successfully${activityType ? ` via ${activityType}` : ''}!`
);
setIsLoading(false);
// Reset status after 3 seconds
setTimeout(() => setStatus('Ready to share'), 3000);
};
const handleShareError = (error: Error) => {
setStatus(`Share failed: ${error.message}`);
setIsLoading(false);
// Reset status after 3 seconds
setTimeout(() => setStatus('Ready to share'), 3000);
};
const handleShareDismiss = () => {
setStatus('Share cancelled');
setIsLoading(false);
// Reset status after 2 seconds
setTimeout(() => setStatus('Ready to share'), 2000);
};
return (
<View style={{ gap: 16 }}>
<Text style={{ fontWeight: '500' }}>Status: {status}</Text>
<ShareButton
content={{
message: 'Check out this awesome React Native component library!',
url: 'https://github.com/example/ui-library',
title: 'UI Component Library',
}}
loading={isLoading}
onShareStart={handleShareStart}
onShareSuccess={handleShareSuccess}
onShareError={handleShareError}
onShareDismiss={handleShareDismiss}
>
Share with Callbacks
</ShareButton>
</View>
);
}
Hook Usage
import { Button } from '@/components/ui/button';
import { useShare } from '@/components/ui/share';
import { Text } from '@/components/ui/text';
import { View } from '@/components/ui/view';
import React, { useState } from 'react';
export function ShareHook() {
const { shareText, shareUrl, shareContent } = useShare();
const [status, setStatus] = useState<string>('Choose a sharing method');
const handleShareText = async () => {
try {
setStatus('Sharing text...');
await shareText(
'Hello from the useShare hook! This is just a plain text message.'
);
setStatus('Text shared successfully!');
} catch (error) {
setStatus(`Failed to share text: ${(error as Error).message}`);
}
};
const handleShareUrl = async () => {
try {
setStatus('Sharing URL...');
await shareUrl(
'https://reactnative.dev',
'Check out the official React Native documentation!'
);
setStatus('URL shared successfully!');
} catch (error) {
setStatus(`Failed to share URL: ${(error as Error).message}`);
}
};
const handleShareContent = async () => {
try {
setStatus('Sharing content...');
await shareContent({
message:
'๐ Just built an amazing React Native app with this component library!',
url: 'https://github.com/example/ui-library',
title: 'Amazing UI Library',
subject: 'Check out this UI library',
});
setStatus('Content shared successfully!');
} catch (error) {
setStatus(`Failed to share content: ${(error as Error).message}`);
}
};
return (
<View style={{ gap: 16 }}>
<Text style={{ fontWeight: '500', textAlign: 'center' }}>{status}</Text>
<View style={{ gap: 8 }}>
<Button onPress={handleShareText} variant='outline'>
Share Text Only
</Button>
<Button onPress={handleShareUrl} variant='secondary'>
Share URL with Message
</Button>
<Button onPress={handleShareContent} variant='default'>
Share Rich Content
</Button>
</View>
</View>
);
}
API Reference
ShareButton
The main share button component that handles native sharing functionality.
Prop | Type | Default | Description |
---|---|---|---|
content | ShareContent | - | Required. The content to be shared. |
options | ShareButtonOptions | - | Platform-specific sharing options. |
children | ReactNode | - | Button content. Shows share icon if not provided. |
variant | ButtonVariant | 'default' | Button visual variant. |
size | 'default' | 'sm' | 'lg' | 'icon' | 'default' | Button size. |
disabled | boolean | false | Whether the button is disabled. |
loading | boolean | false | Whether the button is in loading state. |
onShareStart | () => void | - | Callback when sharing starts. |
onShareSuccess | (activityType?: string) => void | - | Callback when sharing succeeds. |
onShareError | (error: Error) => void | - | Callback when sharing fails. |
onShareDismiss | () => void | - | Callback when share dialog is dismissed. |
showIcon | boolean | true | Whether to show the share icon. |
iconSize | number | 18 | Size of the share icon. |
validateContent | boolean | true | Whether to validate content before sharing. |
testID | string | - | Test identifier for testing. |
ShareContent
The content object that defines what will be shared.
Property | Type | Description |
---|---|---|
message | string | The text message to share. |
url | string | The URL to share. |
title | string | The title for the shared content (iOS only). |
subject | string | The subject line for email sharing (iOS only). |
ShareButtonOptions
Platform-specific options for customizing the share dialog.
Property | Type | Description |
---|---|---|
dialogTitle | string | Title for the share dialog (Android only). |
excludedActivityTypes | string[] | Activity types to exclude from sharing (iOS only). |
tintColor | string | Tint color for the share sheet (iOS only). |
anchor | number | Anchor point for iPad popover (iOS only). |
useShare Hook
A hook that provides programmatic sharing functions without UI components.
Returns
Function | Type | Description |
---|---|---|
shareText | (text: string, options?: ShareButtonOptions) => Promise<any> | Share plain text. |
shareUrl | (url: string, message?: string, options?: ShareButtonOptions) => Promise<any> | Share a URL with optional message. |
shareContent | (content: ShareContent, options?: ShareButtonOptions) => Promise<any> | Share complex content object. |
Platform Differences
iOS
- Supports
title
andsubject
properties in share content - Supports
excludedActivityTypes
,tintColor
, andanchor
options - Share sheet appears as a modal from the bottom
- On iPad, can be anchored to a specific point
Android
- Only supports
message
andurl
in share content - Supports
dialogTitle
option for customizing dialog title - Share dialog appears as a bottom sheet with available apps
Error Handling
The ShareButton component includes comprehensive error handling:
- Invalid Content: Validates that either
message
orurl
is provided - Network Errors: Handles network-related sharing failures
- Permission Errors: Handles cases where sharing permissions are denied
- Unsupported Platform: Handles devices that don't support sharing
Error messages are user-friendly and provide actionable feedback.
Accessibility
The Share component is built with accessibility in mind:
- Uses semantic button structure for screen readers
- Provides appropriate ARIA labels and roles
- Supports dynamic text sizing
- Maintains proper focus management
- Includes loading states for better user feedback
Best Practices
- Content Validation: Always provide either a
message
orurl
in your share content - Error Handling: Implement
onShareError
callback to handle sharing failures gracefully - Loading States: Use the
loading
prop during async operations before sharing - Platform Testing: Test sharing functionality on both iOS and Android devices
- Fallback Options: Consider providing alternative sharing methods if native sharing fails