Top Related Projects
Routing and navigation for your React Native apps
A complete native navigation solution for React Native
React Native's Animated library reimplemented
Material Design for React Native (Android & iOS)
React Native wrapper for the Android ViewPager and iOS UIPageViewController.
Customizable Icons for React Native with support for image source and full styling.
Quick Overview
React Native Tab View is a cross-platform Tab View component for React Native. It provides a flexible and customizable tab navigation solution with smooth animations and gestures. The library supports both top and bottom tab layouts and is highly performant.
Pros
- Cross-platform compatibility (iOS and Android)
- Smooth animations and gestures
- Highly customizable appearance and behavior
- Good performance, even with many tabs
Cons
- Learning curve for complex customizations
- Limited built-in tab styles (requires custom styling for advanced designs)
- Occasional issues with TypeScript definitions
- May require additional setup for certain navigation patterns
Code Examples
- Basic usage with top tabs:
import { TabView, SceneMap } from 'react-native-tab-view';
const FirstRoute = () => (
<View style={{ flex: 1, backgroundColor: '#ff4081' }} />
);
const SecondRoute = () => (
<View style={{ flex: 1, backgroundColor: '#673ab7' }} />
);
const renderScene = SceneMap({
first: FirstRoute,
second: SecondRoute,
});
function MyComponent() {
const [index, setIndex] = React.useState(0);
const [routes] = React.useState([
{ key: 'first', title: 'First' },
{ key: 'second', title: 'Second' },
]);
return (
<TabView
navigationState={{ index, routes }}
renderScene={renderScene}
onIndexChange={setIndex}
/>
);
}
- Custom tab bar:
import { TabBar } from 'react-native-tab-view';
function MyTabBar(props) {
return (
<TabBar
{...props}
indicatorStyle={{ backgroundColor: 'white' }}
style={{ backgroundColor: 'pink' }}
/>
);
}
// Use in TabView:
<TabView
// ...other props
renderTabBar={props => <MyTabBar {...props} />}
/>
- Lazy loading tab content:
<TabView
// ...other props
lazy
renderLazyPlaceholder={() => <ActivityIndicator />}
/>
Getting Started
-
Install the package:
npm install react-native-tab-view
-
Import and use in your React Native app:
import { TabView, SceneMap } from 'react-native-tab-view'; // ... (component code as shown in the first example above)
-
For gesture support, ensure you have
react-native-gesture-handler
installed and properly set up in your project. -
Customize the tab bar, add more tabs, and implement your tab content as needed.
Competitor Comparisons
Routing and navigation for your React Native apps
Pros of react-navigation
- More comprehensive navigation solution, offering various navigation types (stack, drawer, tab, etc.)
- Extensive documentation and community support
- Seamless integration with Redux and other state management libraries
Cons of react-navigation
- Steeper learning curve due to its complexity
- Larger bundle size, which may impact app performance
- More frequent updates and potential breaking changes
Code Comparison
react-navigation:
import { createStackNavigator } from '@react-navigation/stack';
const Stack = createStackNavigator();
function MyStack() {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
);
}
react-native-tab-view:
import { TabView, SceneMap } from 'react-native-tab-view';
const renderScene = SceneMap({
first: FirstRoute,
second: SecondRoute,
});
function MyTabView() {
return (
<TabView
navigationState={{ index, routes }}
renderScene={renderScene}
onIndexChange={setIndex}
/>
);
}
react-navigation provides a more comprehensive navigation solution with various navigation types, extensive documentation, and seamless integration with state management libraries. However, it has a steeper learning curve and larger bundle size. react-native-tab-view focuses specifically on tab navigation, offering a simpler API for implementing tab-based interfaces but with more limited functionality compared to react-navigation's broader feature set.
A complete native navigation solution for React Native
Pros of react-native-navigation
- More comprehensive navigation solution, offering a wider range of navigation patterns
- Native implementation for better performance and smoother transitions
- Extensive customization options for navigation components
Cons of react-native-navigation
- Steeper learning curve due to its complexity and extensive API
- Requires additional setup and linking with native code
- May introduce more dependencies and increase app size
Code Comparison
react-native-tab-view:
import { TabView, SceneMap } from 'react-native-tab-view';
const renderScene = SceneMap({
first: FirstRoute,
second: SecondRoute,
});
<TabView
navigationState={{ index, routes }}
renderScene={renderScene}
onIndexChange={setIndex}
/>
react-native-navigation:
import { Navigation } from 'react-native-navigation';
Navigation.setRoot({
root: {
bottomTabs: {
children: [
{ component: { name: 'FirstTab' } },
{ component: { name: 'SecondTab' } }
]
}
}
});
react-native-tab-view focuses specifically on tab-based navigation, offering a simpler API for implementing tab views. It's lightweight and easy to integrate into existing projects. react-native-navigation, on the other hand, provides a full-featured navigation solution with native implementation, supporting various navigation patterns beyond just tabs. While it offers more flexibility and better performance, it comes with increased complexity and setup requirements.
React Native's Animated library reimplemented
Pros of React Native Reanimated
- More powerful and flexible animation system
- Better performance for complex animations
- Wider range of animation capabilities
Cons of React Native Reanimated
- Steeper learning curve
- More complex setup and configuration
- Potentially overkill for simple tab view implementations
Code Comparison
React Native Tab View:
import { TabView, SceneMap } from 'react-native-tab-view';
const renderScene = SceneMap({
first: FirstRoute,
second: SecondRoute,
});
React Native Reanimated:
import Animated, { useSharedValue, useAnimatedStyle } from 'react-native-reanimated';
const offset = useSharedValue(0);
const animatedStyles = useAnimatedStyle(() => {
return { transform: [{ translateX: offset.value * 255 }] };
});
React Native Tab View is specifically designed for creating tab-based navigation, making it simpler to implement basic tab layouts. It offers a straightforward API and is easier to set up for common tab view scenarios.
React Native Reanimated, on the other hand, is a more general-purpose animation library. It provides a powerful toolset for creating complex animations and gestures, which can be applied to various UI elements, including tab views. While it offers more flexibility and performance optimizations, it requires more setup and a deeper understanding of animation concepts.
Choose React Native Tab View for quick and simple tab implementations, and React Native Reanimated for more advanced, custom animations or when performance is critical for complex UI interactions.
Material Design for React Native (Android & iOS)
Pros of React Native Paper
- Comprehensive UI component library with a wide range of pre-built components
- Follows Material Design guidelines, ensuring a consistent and modern look
- Highly customizable with theming support
Cons of React Native Paper
- Larger bundle size due to the extensive component library
- May require more setup and configuration compared to React Native Tab View
- Some components might be overly complex for simple use cases
Code Comparison
React Native Paper (Tab Navigation):
import { BottomNavigation } from 'react-native-paper';
const MyComponent = () => (
<BottomNavigation
navigationState={{ index, routes }}
onIndexChange={setIndex}
renderScene={renderScene}
/>
);
React Native Tab View:
import { TabView, SceneMap } from 'react-native-tab-view';
const renderScene = SceneMap({
first: FirstRoute,
second: SecondRoute,
});
const MyComponent = () => (
<TabView
navigationState={{ index, routes }}
renderScene={renderScene}
onIndexChange={setIndex}
/>
);
While React Native Paper offers a more comprehensive set of UI components and follows Material Design principles, React Native Tab View focuses specifically on providing a flexible and performant tab navigation solution. The choice between the two depends on the project's requirements, with React Native Paper being more suitable for projects needing a complete UI toolkit, and React Native Tab View being ideal for those primarily seeking a customizable tab navigation system.
React Native wrapper for the Android ViewPager and iOS UIPageViewController.
Pros of react-native-pager-view
- Native implementation for better performance and smoother animations
- Supports vertical paging in addition to horizontal
- Provides more customization options for native behavior
Cons of react-native-pager-view
- Less abstracted API, requiring more setup and configuration
- Fewer built-in components for common use cases like tabs
- May require additional work to achieve cross-platform consistency
Code Comparison
react-native-pager-view:
import PagerView from 'react-native-pager-view';
<PagerView style={styles.pagerView} initialPage={0}>
<View key="1"><Text>First page</Text></View>
<View key="2"><Text>Second page</Text></View>
</PagerView>
react-native-tab-view:
import { TabView, SceneMap } from 'react-native-tab-view';
<TabView
navigationState={{ index, routes }}
renderScene={SceneMap({
first: FirstRoute,
second: SecondRoute,
})}
onIndexChange={setIndex}
/>
react-native-pager-view offers a more low-level approach, giving developers greater control over the paging behavior and appearance. It excels in performance due to its native implementation. However, react-native-tab-view provides a higher-level abstraction, making it easier to implement common tab-based interfaces with less code. The choice between the two depends on the specific requirements of the project, with react-native-pager-view being more suitable for custom paging solutions and react-native-tab-view for quick tab implementations.
Customizable Icons for React Native with support for image source and full styling.
Pros of react-native-vector-icons
- Extensive icon library with multiple icon sets
- Easy customization of icon size, color, and style
- Supports icon fonts and SVG icons
Cons of react-native-vector-icons
- Larger bundle size due to numerous icon sets
- Requires additional setup for iOS projects
- May have performance impact when using many icons
Code Comparison
react-native-vector-icons:
import Icon from 'react-native-vector-icons/FontAwesome';
<Icon name="rocket" size={30} color="#900" />
react-native-tab-view:
import { TabView, SceneMap } from 'react-native-tab-view';
<TabView
navigationState={{ index, routes }}
renderScene={SceneMap({
first: FirstRoute,
second: SecondRoute,
})}
onIndexChange={setIndex}
/>
Summary
react-native-vector-icons is a comprehensive icon library for React Native, offering a wide range of customizable icons. It's ideal for projects requiring diverse icon sets but may increase bundle size. react-native-tab-view, on the other hand, is specifically designed for creating tab-based navigation, providing a more focused solution for this particular UI pattern. The choice between these libraries depends on the specific needs of your project, whether it's extensive icon usage or tab-based navigation.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
The repo has been moved to https://github.com/react-navigation/react-navigation/tree/main/packages/react-native-tab-view. Please open issues and pull requests there.
React Native Tab View
A cross-platform Tab View component for React Native. Implemented using react-native-pager-view
on Android & iOS, and PanResponder on Web, macOS, and Windows.
- Run the example app to see it in action.
- Checkout the example/ folder for source code.
Features
- Smooth animations and gestures
- Scrollable tabs
- Supports both top and bottom tab bars
- Follows Material Design spec
- Highly customizable
- Fully typed with TypeScript
Demo
React Native Compatibility
To use this library you need to ensure you are using the correct version of React Native. If you are using a version of React Native that is lower than 0.63
you will need to upgrade that before attempting to use this library.
react-native-tab-view Version | Required React Native Version |
---|---|
2.x.x | < 0.63 |
3.x.x | >= 0.63 |
Installation
Open a Terminal in the project root and run:
yarn add react-native-tab-view
Now we need to install react-native-pager-view
if you plan to support iOS and Android.
If you are using Expo, to ensure that you get the compatible versions of the libraries, run:
expo install react-native-pager-view
If you are not using Expo, run the following:
yarn add react-native-pager-view
We're done! Now you can build and run the app on your device/simulator.
Quick Start
import * as React from 'react';
import { View, useWindowDimensions } from 'react-native';
import { TabView, SceneMap } from 'react-native-tab-view';
const FirstRoute = () => (
<View style={{ flex: 1, backgroundColor: '#ff4081' }} />
);
const SecondRoute = () => (
<View style={{ flex: 1, backgroundColor: '#673ab7' }} />
);
const renderScene = SceneMap({
first: FirstRoute,
second: SecondRoute,
});
export default function TabViewExample() {
const layout = useWindowDimensions();
const [index, setIndex] = React.useState(0);
const [routes] = React.useState([
{ key: 'first', title: 'First' },
{ key: 'second', title: 'Second' },
]);
return (
<TabView
navigationState={{ index, routes }}
renderScene={renderScene}
onIndexChange={setIndex}
initialLayout={{ width: layout.width }}
/>
);
}
More examples on Snack
API reference
The package exports a TabView
component which is the one you'd use to render the tab view, and a TabBar
component which is the default tab bar implementation.
TabView
Container component responsible for rendering and managing tabs. Follows material design styles by default.
Basic usage look like this:
<TabView
navigationState={{ index, routes }}
onIndexChange={setIndex}
renderScene={SceneMap({
first: FirstRoute,
second: SecondRoute,
})}
/>
TabView Props
navigationState
(required
)
State for the tab view. The state should contain the following properties:
index
: a number representing the index of the active route in theroutes
arrayroutes
: an array containing a list of route objects used for rendering the tabs
Each route object should contain the following properties:
key
: a unique key to identify the route (required)title
: title for the route to display in the tab baricon
: icon for the route to display in the tab baraccessibilityLabel
: accessibility label for the tab buttontestID
: test id for the tab button
Example:
{
index: 1,
routes: [
{ key: 'music', title: 'Music' },
{ key: 'albums', title: 'Albums' },
{ key: 'recents', title: 'Recents' },
{ key: 'purchased', title: 'Purchased' },
]
}
TabView
is a controlled component, which means the index
needs to be updated via the onIndexChange
callback.
onIndexChange
(required
)
Callback which is called on tab change, receives the index of the new tab as argument. The navigation state needs to be updated when it's called, otherwise the change is dropped.
renderScene
(required
)
Callback which returns a react element to render as the page for the tab. Receives an object containing the route as the argument:
const renderScene = ({ route, jumpTo }) => {
switch (route.key) {
case 'music':
return <MusicRoute jumpTo={jumpTo} />;
case 'albums':
return <AlbumsRoute jumpTo={jumpTo} />;
}
};
You need to make sure that your individual routes implement a shouldComponentUpdate
to improve the performance. To make it easier to specify the components, you can use the SceneMap
helper.
SceneMap
takes an object with the mapping of route.key
to React components and returns a function to use with renderScene
prop.
import { SceneMap } from 'react-native-tab-view';
...
const renderScene = SceneMap({
music: MusicRoute,
albums: AlbumsRoute,
});
Specifying the components this way is easier and takes care of implementing a shouldComponentUpdate
method.
Each scene receives the following props:
route
: the current route rendered by the componentjumpTo
: method to jump to other tabs, takes aroute.key
as it's argumentposition
: animated node which represents the current position
The jumpTo
method can be used to navigate to other tabs programmatically:
this.props.jumpTo('albums');
All the scenes rendered with SceneMap
are optimized using React.PureComponent
and don't re-render when parent's props or states change. If you need more control over how your scenes update (e.g. - triggering a re-render even if the navigationState
didn't change), use renderScene
directly instead of using SceneMap
.
IMPORTANT: Do not pass inline functions to SceneMap
, for example, don't do the following:
SceneMap({
first: () => <FirstRoute foo={this.props.foo} />,
second: SecondRoute,
});
Always define your components elsewhere in the top level of the file. If you pass inline functions, it'll re-create the component every render, which will cause the entire route to unmount and remount every change. It's very bad for performance and will also cause any local state to be lost.
If you need to pass additional props, use a custom renderScene
function:
const renderScene = ({ route }) => {
switch (route.key) {
case 'first':
return <FirstRoute foo={this.props.foo} />;
case 'second':
return <SecondRoute />;
default:
return null;
}
};
renderTabBar
Callback which returns a custom React Element to use as the tab bar:
import { TabBar } from 'react-native-tab-view';
...
<TabView
renderTabBar={props => <TabBar {...props} />}
...
/>
If this is not specified, the default tab bar is rendered. You pass this props to customize the default tab bar, provide your own tab bar, or disable the tab bar completely.
<TabView
renderTabBar={() => null}
...
/>
tabBarPosition
Position of the tab bar in the tab view. Possible values are 'top'
and 'bottom'
. Defaults to 'top'
.
lazy
Function which takes an object with the current route and returns a boolean to indicate whether to lazily render the scenes.
By default all scenes are rendered to provide a smoother swipe experience. But you might want to defer the rendering of unfocused scenes until the user sees them. To enable lazy rendering for a particular scene, return true
from getLazy
for that route
:
<TabView
lazy={({ route }) => route.name === 'Albums'}
...
/>
When you enable lazy rendering for a screen, it will usually take some time to render when it comes into focus. You can use the renderLazyPlaceholder
prop to customize what the user sees during this short period.
You can also pass a boolean to enable lazy for all of the scenes:
<TabView
lazy
/>
lazyPreloadDistance
When lazy
is enabled, you can specify how many adjacent routes should be preloaded with this prop. This value defaults to 0
which means lazy pages are loaded as they come into the viewport.
renderLazyPlaceholder
Callback which returns a custom React Element to render for routes that haven't been rendered yet. Receives an object containing the route as the argument. The lazy
prop also needs to be enabled.
This view is usually only shown for a split second. Keep it lightweight.
By default, this renders null
.
keyboardDismissMode
String indicating whether the keyboard gets dismissed in response to a drag gesture. Possible values are:
'auto'
(default): the keyboard is dismissed when the index changes.'on-drag'
: the keyboard is dismissed when a drag begins.'none'
: drags do not dismiss the keyboard.
swipeEnabled
Boolean indicating whether to enable swipe gestures. Swipe gestures are enabled by default. Passing false
will disable swipe gestures, but the user can still switch tabs by pressing the tab bar.
animationEnabled
Enables animation when changing tab. By default it's true.
onSwipeStart
Callback which is called when the swipe gesture starts, i.e. the user touches the screen and moves it.
onSwipeEnd
Callback which is called when the swipe gesture ends, i.e. the user lifts their finger from the screen after the swipe gesture.
initialLayout
Object containing the initial height and width of the screens. Passing this will improve the initial rendering performance. For most apps, this is a good default:
<TabView
initialLayout={{ width: Dimensions.get('window').width }}
...
/>
sceneContainerStyle
Style to apply to the view wrapping each screen. You can pass this to override some default styles such as overflow clipping:
pagerStyle
Style to apply to the pager view wrapping all the scenes.
style
Style to apply to the tab view container.
TabBar
Material design themed tab bar. To customize the tab bar, you'd need to use the renderTabBar
prop of TabView
to render the TabBar
and pass additional props.
For example, to customize the indicator color and the tab bar background color, you can pass indicatorStyle
and style
props to the TabBar
respectively:
const renderTabBar = props => (
<TabBar
{...props}
indicatorStyle={{ backgroundColor: 'white' }}
style={{ backgroundColor: 'pink' }}
/>
);
//...
return (
<TabView
renderTabBar={renderTabBar}
...
/>
);
TabBar Props
getLabelText
Function which takes an object with the current route and returns the label text for the tab. Uses route.title
by default.
<TabBar
getLabelText={({ route }) => route.title}
...
/>
getAccessible
Function which takes an object with the current route and returns a boolean to indicate whether to mark a tab as accessible
. Defaults to true
.
getAccessibilityLabel
Function which takes an object with the current route and returns a accessibility label for the tab button. Uses route.accessibilityLabel
by default if specified, otherwise uses the route title.
<TabBar
getAccessibilityLabel={({ route }) => route.accessibilityLabel}
...
/>
getTestID
Function which takes an object with the current route and returns a test id for the tab button to locate this tab button in tests. Uses route.testID
by default.
<TabBar
getTestID={({ route }) => route.testID}
...
/>
renderIcon
Function which takes an object with the current route, focused status and color and returns a custom React Element to be used as a icon.
<TabBar
renderIcon={({ route, focused, color }) => (
<Icon
name={focused ? 'albums' : 'albums-outlined'}
color={color}
/>
)}
...
/>
renderLabel
Function which takes an object with the current route, focused status and color and returns a custom React Element to be used as a label.
<TabBar
renderLabel={({ route, focused, color }) => (
<Text style={{ color, margin: 8 }}>
{route.title}
</Text>
)}
...
/>
renderTabBarItem
Function which takes a TabBarItemProps
object and returns a custom React Element to be used as a tab button.
renderIndicator
Function which takes an object with the current route and returns a custom React Element to be used as a tab indicator.
renderBadge
Function which takes an object with the current route and returns a custom React Element to be used as a badge.
onTabPress
Function to execute on tab press. It receives the scene for the pressed tab, useful for things like scroll to top.
By default, tab press also switches the tab. To prevent this behavior, you can call preventDefault
:
<TabBar
onTabPress={({ route, preventDefault }) => {
if (route.key === 'home') {
preventDefault();
// Do something else
}
}}
...
/>
onTabLongPress
Function to execute on tab long press, use for things like showing a menu with more options
activeColor
Custom color for icon and label in the active tab.
inactiveColor
Custom color for icon and label in the inactive tab.
pressColor
Color for material ripple (Android >= 5.0 only).
pressOpacity
Opacity for pressed tab (iOS and Android < 5.0 only).
scrollEnabled
Boolean indicating whether to make the tab bar scrollable.
If you set scrollEnabled
to true
, you should also specify a width
in tabStyle
to improve the initial render.
bounces
Boolean indicating whether the tab bar bounces when scrolling.
tabStyle
Style to apply to the individual tab items in the tab bar.
By default, all tab items take up the same pre-calculated width based on the width of the container. If you want them to take their original width, you can specify width: 'auto'
in tabStyle
.
indicatorStyle
Style to apply to the active indicator.
indicatorContainerStyle
Style to apply to the container view for the indicator.
labelStyle
Style to apply to the tab item label.
contentContainerStyle
Style to apply to the inner container for tabs.
style
Style to apply to the tab bar container.
gap
Define a spacing between tabs.
testID
Test id for the tabBar. Can be used for scrolling the tab bar in tests
Using with other libraries
React Navigation
If you want to integrate the tab view with React Navigation's navigation system, e.g. want to be able to navigate to a tab using navigation.navigate
etc, you can use the following official integrations:
- @react-navigation/material-top-tabs for React Navigation 5 & 6
- react-navigation-tabs for React Navigation 4
Note that some functionalities are not available with the React Navigation 4 integration because of the limitations in React Navigation. For example, it's possible to dynamically change the rendered tabs.
Optimization Tips
Avoid unnecessary re-renders
The renderScene
function is called every time the index changes. If your renderScene
function is expensive, it's good idea move each route to a separate component if they don't depend on the index, and use shouldComponentUpdate
or React.memo
in your route components to prevent unnecessary re-renders.
For example, instead of:
const renderScene = ({ route }) => {
switch (route.key) {
case 'home':
return (
<View style={styles.page}>
<Avatar />
<NewsFeed />
</View>
);
default:
return null;
}
};
Do the following:
const renderScene = ({ route }) => {
switch (route.key) {
case 'home':
return <HomeComponent />;
default:
return null;
}
};
Where <HomeComponent />
is a PureComponent
if you're using class components:
export default class HomeComponent extends React.PureComponent {
render() {
return (
<View style={styles.page}>
<Avatar />
<NewsFeed />
</View>
);
}
}
Or, wrapped in React.memo
if you're using function components:
function HomeComponent() {
return (
<View style={styles.page}>
<Avatar />
<NewsFeed />
</View>
);
}
export default React.memo(HomeComponent);
Avoid one frame delay
We need to measure the width of the container and hence need to wait before rendering some elements on the screen. If you know the initial width upfront, you can pass it in and we won't need to wait for measuring it. Most of the time, it's just the window width.
For example, pass the following initialLayout
to TabView
:
const initialLayout = {
height: 0,
width: Dimensions.get('window').width,
};
The tab view will still react to changes in the dimension and adjust accordingly to accommodate things like orientation change.
Optimize large number of routes
If you've a large number of routes, especially images, it can slow the animation down a lot. You can instead render a limited number of routes.
For example, do the following to render only 2 routes on each side:
const renderScene = ({ route }) => {
if (Math.abs(index - routes.indexOf(route)) > 2) {
return <View />;
}
return <MySceneComponent route={route} />;
};
Avoid rendering TabView inside ScrollView
Nesting the TabView
inside a vertical ScrollView
will disable the optimizations in the FlatList
components rendered inside the TabView
. So avoid doing it if possible.
Use lazy
and renderLazyPlaceholder
props to render routes as needed
The lazy
option is disabled by default to provide a smoother tab switching experience, but you can enable it and provide a placeholder component for a better lazy loading experience. Enabling lazy
can improve initial load performance by rendering routes only when they come into view. Refer the prop reference for more details.
Contributing
While developing, you can run the example app to test your changes.
Make sure your code passes TypeScript and ESLint. Run the following to verify:
yarn typescript
yarn lint
To fix formatting errors, run the following:
yarn lint -- --fix
Remember to add tests for your change if possible.
Top Related Projects
Routing and navigation for your React Native apps
A complete native navigation solution for React Native
React Native's Animated library reimplemented
Material Design for React Native (Android & iOS)
React Native wrapper for the Android ViewPager and iOS UIPageViewController.
Customizable Icons for React Native with support for image source and full styling.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot