react-native-boxes
Version:
A react native library for rapid development of UI using boxes
568 lines (413 loc) • 14.7 kB
Markdown
<h1 align="center">React Native Boxes</h1>
<p align="center">
A simple-to-use React Native UI SDK that does all the UI heavy lifting for you —
so you can focus on value, not boilerplate code! Built using barebone react-native and Expo components with almost no third-party dependencies.
</p>
<p align="center">
<img src="https://img.shields.io/badge/Android-3DDC84?style=for-the-badge&logo=android&logoColor=white" alt="Android">
<img src="https://img.shields.io/badge/Web-4285F4?style=for-the-badge&logo=google-chrome&logoColor=white" alt="Web">
<img src="https://img.shields.io/badge/iOS-000000?style=for-the-badge&logo=apple&logoColor=white" alt="iOS">
</p>
<p align="center">
<img src="https://github.com/user-attachments/assets/9174e501-eb08-46ec-8a38-90e8ec8931c5"
alt="collage" width="512px">
</p>
<br>
Out-of-the box comes with:
- Themes
- Layouts (Cards, Vertical, Horizontal, Centered etc.)
- Texts (Title, Subtitle, Text, Caption etc.)
- Buttons (Simple, Transparent, Loading etc.)
- Images and Icons (Icons, Avatars, Images etc.)
- Font (Specify Regular, Styled and Bold fonts)
- Bars (Toolbars, Bottom nav bars etc.)
- Modals (Dialogboxes, Selection bottomsheet, Horizontal selection etc.)
- Expand box (Animated)
- Lists (Simple data list)
- Webview (In app web browser)
- Internationalization (I18n)
- Analytics (Clicks, Impression tracking)
## Install
```
npm install react-native-boxes
```
## Dependencies
Make sure you have following dependencies installed. The versions can be any satisfying version but must not have any breaking changes.
```
"@expo/vector-icons": "^13.0.0",
"react": "^18.2.0",
"@react-native-async-storage/async-storage": "1.23.1",
"react-native": "^0.73.6",
"react-native-safe-area-context": "^4.9.0",
"react-native-gesture-handler":"~2.14.0"
```
## Usage
At the root of your app you must add a theme context and thats it! You are good to go.
```
import { Colors, DarkColors, Theme } from 'react-native-boxes';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
export default function App(){
const colorScheme = 'dark'
const theme = new Theme('my-app', colorScheme === 'dark' ? DarkColors : Colors);
return (
<ThemeContext.Provider value={theme} >
<GestureHandlerRootView>
<WatchlistPage />
</GestureHandlerRootView>
</ThemeContext.Provider>
)
}
```
Optional: If you are also gonna use bottomsheets, Add `GestureHandlerRootView`
## Components
### Themes
Dark colors and Light colors come out of the box.
Dark Colors

Light Colors

<details>
<summary>Customizing theme</summary>
import { Colors, Theme } from 'react-native-boxes';
...
const MyColors = Object.assign(Colors, {
accent: '#086CFE',
accentLight: '#337DFF',
text: '#444444',
caption: '#A9A9A9',
heading: '#222222',
background: '#E6E6E6',
forground: '#fff',
transparent: 'transparent',
semitransparent: '#111a1a1c',
info: '#2196F3',
success: '#4CAF50',
successBackground: '#388E3C',
warning: '#FFA726',
critical: '#F44336',
invert: {
text: '#fff',
caption: '#fff',
heading: '#fff',
background: '#1a1a1c'
}
})
const theme = new Theme('my-app', MyColors);
return (
<ThemeContext.Provider value={theme} >
<WatchlistPage />
</ThemeContext.Provider>
)
</details>
You can also customize sizes, dimensions etc, but it is not recommended.
<details>
<summary>Customizing other theme options</summary>
const theme = new Theme(
appname = '',
colors ,
dimens ,
fonts ,
styles ,
)
</details>
### Fonts
Load the below font names. Different components use different font families.
```
loadAsync({
'Regular': require('./assets/fonts/Regular.ttf'), // Used in all general texts
'Bold': require('./assets/fonts/Bold.ttf'), // Used in Buttons and Headings
'Styled': require('./assets/fonts/Styled.ttf'), // Used in special places
})
```
### Layouts
### VPage
Your root tag for pages. Consists of vertical alignment and some basic padding.

<details>
<summary>Code sample</summary>
<VPage>
<Title>Watchlist1</Title>
</VPage>
</details>
#### Center

<details>
<summary>Code sample</summary>
<Center>
<Title>Watchlist</Title>
<Caption>Coming soon </Caption>
</Center>
</details>
#### VBox

<details>
<summary>Code sample</summary>
<VBox>
<Title>Watchlist</Title>
<Caption>Coming soon </Caption>
</VBox>
</details>
#### HBox

<details>
<summary>Code sample</summary>
<HBox>
<Title>Watchlist1</Title>
<Title>Watchlist2</Title>
</HBox>
</details>
### Texts

<details>
<summary>Code sample</summary>
Icons are from Fontawesome
https://icons.expo.fyi/Index
<Title>Watchlist Title</Title>
<TextView>
This is a text with a simple example from a watchlist screen. You can add stocks to your watchlist and see their performance. You can also add alerts to get notified when a stock reaches a certain price.
</TextView>
<Subtitle>This is a subtitle for watchlist</Subtitle>
<TitleText>
This is a title text that explains what a watchlist is.
</TitleText>
<TextView>
A watchlist is a list of stocks that you are interested in.
</TextView>
<TitleText>
This is a another title text that explains what a watchlist is.
</TitleText>
<TextView>
A watchlist is a list of stocks that you are interested in.
</TextView>
<Caption>
This is a caption. All investments are subject to market risk. Please do your own research before investing in any stock. This app is for educational purposes only.
</Caption>
</details>
### Images
#### Avatars

- With icon
- With image url
- With text
<details>
<summary>Code sample</summary>
<Avatar iconName='user' />
<Avatar iconUrl='https://avatars.githubusercontent.com/u/16799797?v=4' />
<Avatar iconText='SN' />
</details>
#### Icons
Support for Fontawesome icon names from https://icons.expo.fyi/

<details>
<summary>Code sample</summary>
<Icon name='home' size={50} />
<Title>Light Theme Watchlist</Title>
</details>
### Buttons
<details>
<summary>Simple button code sample</summary>
<ButtonView text='Simple Button' />
</details>

<details>
<summary>Transparent button code sample</summary>
<TransparentButton text='Transparent Button' />
</details>

<details>
<summary>Loading button code sample</summary>
const [loading, setLoading] = useState(false)
<LoadingButton loading={loading} text='Loading Button' onPress={() => {
setLoading((prev) => !prev)
}} />
</details>

### Bottombar

<details>
<summary>Code sample</summary>
Icons are from Fontawesome
https://icons.expo.fyi/Index
export default function AppBottomBar() {
const theme = useContext(ThemeContext)
const router = useRouter()
const [selectedId, setSelectedId] = React.useState('watchlist')
return (
<BottomNavBar
selectedId={selectedId}
options={[
{
id: 'watchlist',
icon: 'bookmark',
title: 'Watchlist'
},
{
id: 'orders',
icon: 'file-text',
title: 'Orders'
},
{
id: 'positions',
icon: 'briefcase',
title: 'Positions'
},
{
id: 'settings',
icon: 'gears',
title: 'Settings'
}
]}
onSelect={(selectedId) => {
console.log('selected', selectedId)
setSelectedId(selectedId)
router.push('/explore')
}} />
)
}
</details>
### Expand

<details>
<summary>Code sample</summary>
<Expand title='Expand Watchlist' >
<TextView>INFY</TextView>
<TextView>TCS</TextView>
</Expand>
</details>
### Toolbars
### Simple Toolbar

<details>
<summary>Code sample</summary>
<SimpleToolbar title="Watchlist" />
</details>
### Transparent Center Toolbar

<details>
<summary>Code sample</summary>
<SimpleToolbar title="Watchlist" />
</details>
### Toolbar with buttons

<details>
<summary>Code sample</summary>
<TransparentCenterToolbar
homeIcon={"arrow-left"}
title="Watchlist"
options={[{
id: 'search',
icon: 'search',
onClick: () => {
console.log('Search clicked')
}
}]}
/>
</details>
### Divider

<details>
<summary>Code sample</summary>
<Expand title='Expand Watchlist' >
<TextView>INFY</TextView>
<TextView>TCS</TextView>
</Expand>
</details>
### Modals
#### Bottomsheet on mobile

<details>
<summary>Code sample</summary>
<BottomSheet title="Bottomsheet About Watchlists" visible={showDialog} onDismiss={() => setShowDialog(false)}>
<TextView>
This is a simple dialog that can be used to show more information to the user. It is a bottom sheet that can host any content.
</TextView>
<HBox />
<TextView>
Watchlists are a great way to keep track of your favorite stocks. You can add stocks to your watchlist and see their performance. You can also add alerts to get notified when a stock reaches a certain price.
</TextView>
<TertiaryButtonView text='Goto Watchlist' onPress={() => setShowDialog(false)} />
</BottomSheet>
</details>
#### Bottomsheet on Desktop (web)

### Web view
Opens a webview on native and a `iframe` on Web
<details>
<summary>Code sample</summary>
<WebBrowserView url='https://www.google.com' title='Google'/>
</details>
### Internationalization
Install your favorite js library.

<details>
<summary>Code sample</summary>
import { I18n } from 'i18n-js';
const I18nProvider = new I18n({
en: {
watchlist: {
hello: 'Hello!'
}
},
hi: {
watchlist: {
hello: 'नमस्ते !'
}
},
hinglish: {
watchlist: {
hello: 'Namaste !'
}
},
es: {
watchlist: {
hello: 'Hola!'
}
}
});
I18nProvider.missingBehavior = "guess";
export default function App(){
const [locale, setLocale] = useState('en')
I18nProvider.locale = locale
const theme = new Theme('appname', colorScheme === 'dark' ? DarkColors : Colors);
theme.i18n = I18nProvider
return (
<ThemeContext.Provider value={theme} >
<Center>
<Title>watchlist.hello</Title>
</Center>
<Center>
<HBox>
<TransparentButton text='English' onPress={() => {
setLocale('en')
}} />
<TransparentButton text='Hindi' onPress={() => {
setLocale('hi')
}} />
</HBox>
<HBox>
<TransparentButton text='Hinglish' onPress={() => {
setLocale('hinglish')
}} />
<TransparentButton text='Spanish' onPress={() => {
setLocale('es')
}} />
</HBox>
</Center>
</ThemeContext.Provider>
)
}
</details>
### Analytics
If you wanna track the users clicks and impressions on each component, just add a `onTrack` hook to your theme.
```
action : TrackingActionType = click | view | navigate
view : TrackingViewType = button | dropdown...
text : The text related to the component if present
extra : Depending on component, some contextual info. For e.g. the WebView impression gives {url, title} extra
```
<details>
const theme = new Theme('appname', DarkColors);
theme.onTrack = (action, view, text, extras) => {
myTracker.track(`${action}-${text}-${text}`, extras)
}
</details>