react-native-web-elements
v1.1.15
Published
Element like html in react-native. Easy for react-developer to use
Downloads
34
Maintainers
Readme
react-native-web-elements
A modern, theme-aware UI library for React Native. Designed to feel like HTML for React developers, with support for Dark Mode, Animated components, and robust inputs. Every component is built on core react-native primitives, so behavior is consistent on both iOS and Android.
Installation
npm install react-native-web-elementsThis package has peer dependencies that must be installed in your app:
npm install react react-native react-native-safe-area-contextreact-native-safe-area-context contains native code. If you're on a bare React Native project (not Expo), install pods after adding it:
cd ios && pod installIf you're on Expo, use the Expo-managed install instead so the native version matches your SDK:
npx expo install react-native-safe-area-contextThen wrap your app's root in a SafeAreaProvider (required by react-native-safe-area-context, used internally by Input):
import { SafeAreaProvider } from 'react-native-safe-area-context';
export default function Root() {
return (
<SafeAreaProvider>
<App />
</SafeAreaProvider>
);
}Features
- Theming: Built-in support for Light and Dark modes.
- Modern Styles: Standard React Native
StyleSheet, nostyled-componentsdependency. - Enhanced Components: Underlined/Bordered Inputs with Floating Labels.
- 30+ Components: Buttons, Inputs, Dropdown, Checkbox, RadioButton, FileUpload, Skeleton Loader, Avatar, Switch, ProgressBar, Divider, Chip, Rating, Tabs, ListItem, and more.
- Animations: Ready-to-use FadeIn, SlideIn, and Scale animations.
- Performance: Static styles hoisted to
StyleSheet.create, and presentational components wrapped inReact.memoto avoid unnecessary re-renders in lists. - Cross-platform: Every component renders from core RN APIs (
View,Text,Animated,TouchableOpacity, ...) — no platform-specific forks needed.
Quick Start
Wrap your app's root component with ThemeProvider. It defaults to the device's color scheme, and exposes useTheme() to read/toggle theme anywhere.
import { ThemeProvider } from 'react-native-web-elements';
export default function App() {
return (
<ThemeProvider>
{/* Your components */}
</ThemeProvider>
);
}import { useTheme } from 'react-native-web-elements';
const { theme, themeMode, toggleTheme, setMode } = useTheme();
// theme.colors.primary, theme.spacing.md, theme.borderRadius.lg, theme.typography.h1, ...
// toggleTheme() flips light/dark, setMode('dark') sets it explicitlyComponents
Button
import { Button } from 'react-native-web-elements';
<Button onPress={() => alert('Hello!')}>Click Me</Button>
<Button bordered color="#FF3B30" onPress={() => {}}>Delete</Button>
<Button size={200} textColor="#fff" onPress={() => {}}>Fixed Width</Button>Props: children, color, bordered, onPress, customStyle, size, textColor.
Input (legacy)
Basic KeyboardAvoidingView-wrapped text input. Kept for backwards compatibility — prefer InputV2 for new code.
import { Input } from 'react-native-web-elements';
<Input label="Email" value={email} onChangeText={setEmail} bordered borderColor="#ccc" />InputV2 (recommended)
Themed input with floating-label animation, bordered/underlined variants, and error text.
import { InputV2 } from 'react-native-web-elements';
<InputV2
label="Full Name"
floatingLabel
bordered
placeholder="Enter your name"
value={name}
onChangeText={setName}
/>
<InputV2 label="Bio" multiline value={bio} onChangeText={setBio} underlined />
<InputV2 label="Email" value={email} onChangeText={setEmail} error="Invalid email address" />Props: error, center, label, mv, bordered, underlined, floatingLabel, value, onChangeText, borderColor, multiline, plus any standard TextInput prop.
Dropdown
Single or multi-select with a modal picker and optional removable chips.
import { Dropdown } from 'react-native-web-elements';
const options = [
{ label: 'React', value: 'react' },
{ label: 'React Native', value: 'rn' },
];
<Dropdown
label="Skills"
options={options}
multiple
chip
value={selectedSkills}
onSelect={setSelectedSkills}
/>
<Dropdown label="Country" options={countries} value={country} onSelect={setCountry} />Checkbox
import { Checkbox } from 'react-native-web-elements';
<Checkbox label="Agree to Terms" checked={agreed} onChange={setAgreed} />RadioButton / RadioGroup
import { RadioGroup } from 'react-native-web-elements';
<RadioGroup
label="Payment method"
options={[
{ label: 'Credit Card', value: 'card' },
{ label: 'PayPal', value: 'paypal' },
]}
value={method}
onChange={setMethod}
/>FileUpload
import { FileUpload } from 'react-native-web-elements';
<FileUpload
label="Resume"
fileName={file?.name}
placeholder="Tap to upload your resume"
onPress={pickDocument}
error={fileError}
/>Spinner
import { Spinner } from 'react-native-web-elements';
<Spinner size="large" color="#007AFF" />Loader
Full-screen modal overlay spinner.
import { Loader } from 'react-native-web-elements';
<Loader visible={isSubmitting} text="Loading..." />Skeleton
Animated placeholder for loading content.
import { Skeleton } from 'react-native-web-elements';
<Skeleton width={200} height={20} />
<Skeleton width="100%" height={120} borderRadius={12} />Avatar
import { Avatar } from 'react-native-web-elements';
<Avatar name="John Doe" size={48} />
<Avatar source={{ uri: 'https://example.com/avatar.png' }} size={64} />
<Avatar name="AB" rounded={false} color="#0A84FF" />Switch
Animated themed toggle — visually consistent across iOS/Android (unlike the platform-default Switch).
import { Switch } from 'react-native-web-elements';
<Switch value={enabled} onValueChange={setEnabled} />ProgressBar
import { ProgressBar } from 'react-native-web-elements';
<ProgressBar progress={0.6} />
<ProgressBar progress={downloadProgress} color="#4CD964" height={12} />Divider
import { Divider } from 'react-native-web-elements';
<Divider />
<Divider vertical thickness={1} style={{ height: 20 }} />Chip
import { Chip } from 'react-native-web-elements';
<Chip label="React Native" selected onClose={() => removeTag('rn')} />
<Chip label="Beginner" onPress={() => setLevel('beginner')} />Rating
import { Rating } from 'react-native-web-elements';
<Rating value={rating} onChange={setRating} />
<Rating value={4} max={10} size={20} disabled />Tabs
Segmented control.
import { Tabs } from 'react-native-web-elements';
<Tabs
tabs={[
{ label: 'Posts', value: 'posts' },
{ label: 'About', value: 'about' },
]}
value={activeTab}
onChange={setActiveTab}
/>ListItem
import { ListItem, Avatar } from 'react-native-web-elements';
<ListItem
title="Jane Cooper"
subtitle="Product Designer"
left={<Avatar name="Jane Cooper" size={40} />}
onPress={() => openProfile('jane')}
bottomDivider
/>Card / CardComponent
import { CardComponent, Button, H5 } from 'react-native-web-elements';
<CardComponent title="My Card" footer="Updated 2 hours ago">
<H5>Welcome to the new elements!</H5>
<Button onPress={() => alert('Hello!')}>Click Me</Button>
</CardComponent>Animated Views
import { FadeInView, SlideInView, ScaleView } from 'react-native-web-elements';
<FadeInView duration={1000}>
<Text>I'm fading in smoothly.</Text>
</FadeInView>
<SlideInView from="bottom">
<Text>I'm sliding up!</Text>
</SlideInView>
<ScaleView onPress={() => {}} scale={0.9}>
<Text>Press me — I shrink!</Text>
</ScaleView>HTML-like Layout Primitives
Low-level building blocks used throughout the library, exported for direct use:
import {
Container, Row, Div, Body, Center, Header,
H1, H2, H3, H4, H5, H6,
Card, CardHeader, CardBody, CardFooter,
Left, Right, Image, Badge, IconWrapper, CircleTextWrapper, DotCircle,
FormGroup, FGNoFlex, BorderedButton, BodyContainer, PickerWrapper, CalenderWrapper,
} from 'react-native-web-elements';
<Container>
<Header><H3>My App</H3></Header>
<Row justify="space-between">
<H5>Left text</H5>
<Badge bgColor="#4CD964"><H6 color="white">New</H6></Badge>
</Row>
</Container>Responsive Utilities
Scale sizes relative to a base design resolution — useful for consistent sizing across different device screens.
import { scale, verticalScale, moderateScale, SCREEN_WIDTH, SCREEN_HEIGHT } from 'react-native-web-elements';
const styles = {
title: { fontSize: moderateScale(18) },
banner: { height: verticalScale(120), width: scale(300) },
};Customization
Pass custom themes or toggle themes manually using the useTheme hook:
import { useTheme } from 'react-native-web-elements';
const { toggleTheme, themeMode } = useTheme();Or start ThemeProvider pinned to a specific mode instead of following the device:
<ThemeProvider initialTheme="dark">
<App />
</ThemeProvider>Storybook Demo
The example/ folder is a bare React Native app that hosts an on-device Storybook (@storybook/react-native) for every component in this library. Stories live next to each component's source as src/**/*.stories.js and are picked up automatically.
Setup (one-time):
cd example
npm install
cd ios && bundle install && bundle exec pod install && cd ..Run it:
# Terminal 1 — start Metro from the example folder
cd example
npm start
# Terminal 2 — build and launch the app
npm run ios # or: npm run androidThe app entry (App.tsx) renders the Storybook UI directly. Use the on-device navigator (bottom bar) to browse components, the Controls addon to tweak props live, and the Actions addon to see onPress/onChange calls logged in real time.
Metro is configured (example/metro.config.js) to watch the parent package's src/ directory and dedupe react/react-native/react-native-safe-area-context to the example's copies, so edits to any component under src/ hot-reload straight into Storybook — no npm run build needed for the example app (that's only required when publishing the package itself).
To add a story for a new component, create src/YourComponent/index.stories.js:
import YourComponent from './index';
const meta = {
title: 'YourComponent',
component: YourComponent,
};
export default meta;
export const Default = {
args: { /* props */ },
};Contributing
Created by Avanish Mishra. License: ISC.
