├── .gitignore
├── .github
└── dependabot.yml
├── changelog.md
├── lib
├── index.d.ts
└── index.js
├── tsconfig.json
├── package.json
├── src
└── index.tsx
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | # node.js
2 | #
3 | node_modules/
4 | npm-debug.log
5 | yarn-error.log
6 | package-lock.json
7 | yarn.lock
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: npm
4 | directory: "/"
5 | schedule:
6 | interval: daily
7 | time: "23:30"
8 | open-pull-requests-limit: 10
9 |
--------------------------------------------------------------------------------
/changelog.md:
--------------------------------------------------------------------------------
1 | #### Version 1.0.13
2 |
3 | 1. stupid package.json infinite loop fix
4 |
5 |
6 | #### Version 1.0.12
7 |
8 | 1. Removed the `react-native-device-info` as a peerDepenency
9 | 2. Added ChangeLog.md
10 | 3. Updated Readme.md
11 |
12 |
13 |
--------------------------------------------------------------------------------
/lib/index.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | import { StatusBarProps } from 'react-native';
3 | export interface SafeAreaDeciderProps {
4 | statusBarHiddenForNotch: boolean;
5 | statusBarHiddenForNonNotch: boolean;
6 | backgroundColor?: string;
7 | }
8 | declare const SafeAreaDecider: ({ statusBarHiddenForNotch, statusBarHiddenForNonNotch, backgroundColor, ...rest }: SafeAreaDeciderProps & StatusBarProps) => JSX.Element | null;
9 | export default SafeAreaDecider;
10 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "include": ["src"],
4 | "exclude": [
5 | "node_modules",
6 | "babel.config.js",
7 | "metro.config.js",
8 | "jest.config.js"
9 | ],
10 | "compilerOptions": {
11 | "lib": ["es5", "es6", "esnext.asynciterable"],
12 | "allowSyntheticDefaultImports": false,
13 | "esModuleInterop": false,
14 | "jsx": "react",
15 | "moduleResolution": "node",
16 | "strict": true,
17 | "target": "esnext",
18 | "resolveJsonModule": true,
19 | "outDir": "./lib",
20 | "declaration": true
21 | }
22 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-smart-statusbar",
3 | "version": "1.0.24",
4 | "description": "The smart status bar for react-native that intelligently handles safe area across iOS and Android, background color etc",
5 | "main": "lib/index.js",
6 | "types": "lib",
7 | "scripts": {
8 | "build": "npm run prettier:write && tsc -p .",
9 | "prettier:base": "prettier --parser typescript --single-quote",
10 | "prettier:check": "npm run prettier:base -- --list-different \"src/**/*.tsx\"",
11 | "prettier:write": "npm run prettier:base -- --write \"src/**/*.tsx\""
12 | },
13 | "husky": {
14 | "hooks": {
15 | "pre-commit": "lint-staged"
16 | }
17 | },
18 | "lint-staged": {
19 | "src/**/*.tsx": [
20 | "npm run prettier:write",
21 | "git add"
22 | ]
23 | },
24 | "repository": {
25 | "type": "git",
26 | "url": "git+https://github.com/irohitb/react-native-smart-statusbar.git"
27 | },
28 | "keywords": [
29 | "react-native",
30 | "status-bar",
31 | "react-native-status-bar",
32 | "safe-area",
33 | "safearea",
34 | "react-native-safe-area"
35 | ],
36 | "author": "",
37 | "license": "MIT",
38 | "bugs": {
39 | "url": "https://github.com/irohitb/react-native-smart-statusbar/issues"
40 | },
41 | "devDependencies": {
42 | "@types/react-native": "^0.64.2",
43 | "husky": "^7.0.1",
44 | "lint-staged": "^10.2.10",
45 | "prettier": "^2.0.5",
46 | "typescript": "^4.1.3"
47 | },
48 | "homepage": "https://github.com/irohitb/react-native-smart-statusbar#readme",
49 | "peerDependencies": {
50 | "react": ">=16.12.0",
51 | "react-native": ">=0.61",
52 | "react-native-device-info": ">=5.4.1"
53 | },
54 | "dependencies": {
55 | "react-native-device-info": "^8.1.5"
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import DeviceInfo from 'react-native-device-info';
3 | import { View, StatusBar, Platform, Dimensions, } from 'react-native';
4 | const SafeAreaDecider = ({ statusBarHiddenForNotch = false, statusBarHiddenForNonNotch = false, backgroundColor, ...rest }) => {
5 | const [state, setState] = React.useState({
6 | navbarHeight: '',
7 | deviceHaveNotch: false,
8 | });
9 | const isComponentMounted = React.useRef(true);
10 | React.useEffect(() => {
11 | async function setNotchProperties() {
12 | const deviceHaveNotch = await DeviceInfo.hasNotch();
13 | if (isComponentMounted.current) {
14 | const iOSHeight = deviceHaveNotch ? 44 : 20;
15 | setState({
16 | navbarHeight: iOSHeight,
17 | deviceHaveNotch: deviceHaveNotch,
18 | });
19 | }
20 | else if (Platform.OS === 'android') {
21 | setState({
22 | navbarHeight: StatusBar.currentHeight,
23 | deviceHaveNotch: deviceHaveNotch,
24 | });
25 | }
26 | }
27 | setNotchProperties();
28 | return () => {
29 | isComponentMounted.current = false;
30 | };
31 | }, []);
32 | const { deviceHaveNotch, navbarHeight } = state;
33 | if (deviceHaveNotch) {
34 | return (React.createElement(View, { style: {
35 | height: navbarHeight || '',
36 | backgroundColor: backgroundColor,
37 | width: Dimensions.get('window').width,
38 | } },
39 | React.createElement(StatusBar, { ...rest, translucent: true, hidden: statusBarHiddenForNotch })));
40 | }
41 | else if (!deviceHaveNotch && Platform.OS === 'ios') {
42 | return (React.createElement(View, { style: {
43 | backgroundColor: backgroundColor,
44 | width: Dimensions.get('window').width,
45 | } },
46 | React.createElement(StatusBar, { ...rest, translucent: true, hidden: statusBarHiddenForNonNotch })));
47 | }
48 | else if (!deviceHaveNotch && Platform.OS === 'android') {
49 | return (React.createElement(StatusBar, { ...rest, backgroundColor: backgroundColor, hidden: statusBarHiddenForNonNotch }));
50 | }
51 | else {
52 | return null;
53 | }
54 | };
55 | export default SafeAreaDecider;
56 |
--------------------------------------------------------------------------------
/src/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import DeviceInfo from 'react-native-device-info';
3 | import {
4 | View,
5 | StatusBarProps,
6 | StatusBar,
7 | Platform,
8 | Dimensions,
9 | } from 'react-native';
10 |
11 | export interface SafeAreaDeciderProps {
12 | statusBarHiddenForNotch: boolean;
13 | statusBarHiddenForNonNotch: boolean;
14 | backgroundColor?: string;
15 | }
16 |
17 | interface Istate {
18 | navbarHeight?: number | ''; //StatusBar.currentHeight gives undefined
19 | deviceHaveNotch: boolean;
20 | }
21 | const SafeAreaDecider = ({
22 | statusBarHiddenForNotch = false,
23 | statusBarHiddenForNonNotch = false,
24 | backgroundColor,
25 | ...rest
26 | }: SafeAreaDeciderProps & StatusBarProps) => {
27 | const [state, setState] = React.useState({
28 | navbarHeight: '',
29 | deviceHaveNotch: false,
30 | });
31 |
32 | const isComponentMounted = React.useRef(true);
33 | React.useEffect(() => {
34 | async function setNotchProperties() {
35 | const deviceHaveNotch = await DeviceInfo.hasNotch();
36 | if (isComponentMounted.current) {
37 | const iOSHeight = deviceHaveNotch ? 44 : 20;
38 | setState({
39 | navbarHeight: iOSHeight,
40 | deviceHaveNotch: deviceHaveNotch,
41 | });
42 | } else if (Platform.OS === 'android') {
43 | setState({
44 | navbarHeight: StatusBar.currentHeight,
45 | deviceHaveNotch: deviceHaveNotch,
46 | });
47 | }
48 | }
49 | setNotchProperties();
50 | return () => {
51 | isComponentMounted.current = false;
52 | };
53 | }, []);
54 | const { deviceHaveNotch, navbarHeight } = state;
55 | if (deviceHaveNotch) {
56 | return (
57 |
64 |
65 |
66 | );
67 | } else if (!deviceHaveNotch && Platform.OS === 'ios') {
68 | return (
69 |
75 |
76 |
77 | );
78 | } else if (!deviceHaveNotch && Platform.OS === 'android') {
79 | return (
80 |
85 | );
86 | } else {
87 | return null;
88 | }
89 | };
90 |
91 | export default SafeAreaDecider;
92 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React-Native-Smart-Status-Bar
2 |
3 | | | Status |
4 | | - | - |
5 | | Dependencies | [](https://david-dm.org/blendtale/react-native-smart-statusbar) [](https://david-dm.org/blendtale/react-native-smart-statusbar) [](https://david-dm.org/blendtale/react-native-smart-statusbar)|
6 | | Package | [](https://www.npmjs.com/package/react-native-smart-statusbar) [](https://www.npmjs.com/package/react-native-smart-statusbar) 
7 |
8 | React Native Provides with Certain Api's whose scope is limited to either iOS or Android. With React-Native-Smart-Status-Bar we try to make status bar consistent across both Android iOS.
9 |
10 | Basically, It handles safe area and background color across iOS and Android.
11 |
12 | ### Note
13 | - If you find this repo interesting do not forgot to give it a star.
14 | - If you have a feature request than open it on github and feature should be added within 2-7 days (author of the repo would keep you updated)
15 | - If you find a bug, open an issue on github and author would fix it less than 24 hours
16 |
17 | ## Installation
18 |
19 | ```
20 | npm i react-native-device-info
21 | npm i react-native-smart-statusbar
22 | ```
23 |
24 | #### For IOS
25 |
26 | ```
27 | cd ios
28 | pod install
29 | ```
30 |
31 | for people using RN <= 0.59, please read the installation instruction from `react-native-device-info` [repo](https://github.com/react-native-community/react-native-device-info)
32 |
33 |
34 | ## Usage
35 |
36 | ```
37 |
38 | ```
39 |
40 | ## Props
41 |
42 | React-Native-Smart-Status-Bar takes three things as props
43 |
44 | | **Prop** | **Type** | **Default** | **Required** | **description** |
45 | |----------|----------|-------------|--------------|--------------|
46 | | statusBarHiddenForNotch | boolean | false | No | Determines if status bar needs to be hidden or not for notch device |
47 | | statusBarHiddenForNonNotch | boolean | false | No | Determines if status bar needs to be hidden or not for non notch device|
48 | | backgroundColor | string | null | No | Adds background color consistent across iOS and Android device for Status bar |
49 |
50 |
51 | The React Native status bar also extends all the [status bar props](https://facebook.github.io/react-native/docs/statusbar)
52 |
53 |
54 | ## Examples
55 |
56 | Note: If you don't provide background color, it will take background as white by default
57 |
58 | ### Example 1: Hidden for Notch with Background color null
59 |
60 | ```
61 |
62 | ```
63 |
64 | Result:
65 |
66 |
67 |
68 |
69 | ### Example 2: Hidden for notch with Background color provided
70 |
71 | ```
72 |
73 | ```
74 |
75 | Result:
76 |
77 |
78 |
79 |
80 | ### Example 3: Hidden for non notch with Background color provided
81 |
82 | ```
83 |
84 | ```
85 |
86 | Result:
87 |
88 |
89 |
90 |
91 |
92 | ### Recent changes
93 |
94 | 1. Check changelog.md for all the changes
95 |
--------------------------------------------------------------------------------