Skip to content

Commit

Permalink
Feature/storybook (#14)
Browse files Browse the repository at this point in the history
* feat: add react native storybook

* Update storybook readme with enjoyable music

Have fun
  • Loading branch information
mthuong authored May 16, 2021
1 parent 8c0b989 commit 352b0b2
Show file tree
Hide file tree
Showing 27 changed files with 5,673 additions and 153 deletions.
11 changes: 11 additions & 0 deletions template/.env.storybook
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
ENVIRONMENT='storybook'
APP_IDENTIFIER='com.ios.dev'
APP_NAME='App Storybook'
ANDROID_APP_ID='com.android.dev'
APK_NAME='apk_name'
#################################
IOS_APP_VERSION_NUMBER=0.1
ANDROID_APP_VERSION_NUMBER=0.1
APP_VERSION_CODE=1
#################################
LOAD_STORYBOOK=true
4 changes: 3 additions & 1 deletion template/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import Navigator from './src/navigator/Navigator'
import { GlobalSnackBar } from './src/components/SnackBar/GlobalSnackBar'
import LocalizationProvider from './src/localization'
import { ThemeProvider } from './src/theme'
import StorybookUI from './storybook'
import Config from 'react-native-config'

// Enable screens support before any of your navigation screens renders
enableScreens()
Expand All @@ -37,4 +39,4 @@ const App = () => {
)
}

export default App
export default Config.LOAD_STORYBOOK === 'true' ? StorybookUI : App
28 changes: 27 additions & 1 deletion template/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
## Getting Started

### Firebase setup
![image](https://user-images.githubusercontent.com/1086057/118397628-29018780-b67f-11eb-941a-8adeb02cb697.png)

<details close><summary><b>Show instructions</b></summary>

Expand All @@ -87,6 +88,7 @@
</details>

### Firestore setup for Chat function
![image](https://user-images.githubusercontent.com/1086057/118397565-d88a2a00-b67e-11eb-8f01-737f5841fbc2.png)

<details close><summary><b>Show instructions</b></summary>

Expand Down Expand Up @@ -134,6 +136,7 @@ service cloud.firestore {
</details>

### Icomoon
![image](https://user-images.githubusercontent.com/1086057/118397752-c6f55200-b67f-11eb-86bc-7921b44a0565.png)

<details close><summary><b>Show instructions</b></summary>

Expand Down Expand Up @@ -163,6 +166,7 @@ service cloud.firestore {
</details>

### Fonts
![image](https://user-images.githubusercontent.com/1086057/118397857-3bc88c00-b680-11eb-932a-3722f738b942.png)

<details close><summary><b>Show instructions</b></summary>

Expand All @@ -182,9 +186,31 @@ src/theme/fonts/index.tsx
</details>

### Storybook
![image](https://user-images.githubusercontent.com/1086057/118398015-ef318080-b680-11eb-9cdf-24bbb26503e9.png)

Unmuted and enjoy 🤣🤣🤣 🇻🇳🇻🇳🇻🇳

https://user-images.githubusercontent.com/1086057/118398672-e1312f00-b683-11eb-80c0-f3f37513010c.mp4

<details close><summary><b>Show instructions</b></summary>
- Storybook - https://github.com/storybookjs/react-native -
1. Storybook document - https://storybook.js.org/tutorials/intro-to-storybook/react-native/en/get-started/

2. iOS
```ruby
yarn istorybook
```

3. Android
```ruby
yarn astorybook
```

4. Use Storybook server (Optional)
```ruby
yarn storybook
```
Then reload your simulator or device

</details>

<!-- CONTACT -->
Expand Down
4 changes: 4 additions & 0 deletions template/__mocks__/globalMock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
jest.mock('global', () => ({
...global,
WebSocket: function WebSocket() {},
}))
10 changes: 5 additions & 5 deletions template/ios/HelloWorld.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
26964ECF11424BBBAF5C6246 /* FontAwesome.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9FD5FE6F2AF9442CA8A73334 /* FontAwesome.ttf */; };
27AB936DBA814D1A95CC2BD5 /* Feather.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 652DB4899AB641598A408686 /* Feather.ttf */; };
2895505E0EA94CC99A67ECD6 /* Zocial.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 83D82A594DB24F6794F576B6 /* Zocial.ttf */; };
2C5B7E7658654308A66515A9 /* icomoon.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D987AA3C470B4B6D8E7B951D /* icomoon.ttf */; };
2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
Expand All @@ -36,7 +37,6 @@
EDAEA73BE383B20D3A6898BA /* libPods-HelloWorld-HelloWorldTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 423C233C1047685AB6DE5C98 /* libPods-HelloWorld-HelloWorldTests.a */; };
F0DD979CBF1A451780BFD516 /* Fontisto.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 4DD2DFCFA9744CA0A48D60A7 /* Fontisto.ttf */; };
F329BEF7894D474AB323705B /* Entypo.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 72657EBC53EF451484F32F03 /* Entypo.ttf */; };
2C5B7E7658654308A66515A9 /* icomoon.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D987AA3C470B4B6D8E7B951D /* icomoon.ttf */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand All @@ -62,7 +62,7 @@
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
00E356F21AD99517003FC87E /* HelloWorldTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HelloWorldTests.m; sourceTree = "<group>"; };
0367AE3825F8D56300111423 /* Config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = "<group>"; };
13B07F961A680F5B00A75B9A /* App Dev.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "App Dev.app"; sourceTree = BUILT_PRODUCTS_DIR; };
13B07F961A680F5B00A75B9A /* App Storybook.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "App Storybook.app"; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = HelloWorld/AppDelegate.h; sourceTree = "<group>"; };
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = HelloWorld/AppDelegate.m; sourceTree = "<group>"; };
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = HelloWorld/Images.xcassets; sourceTree = "<group>"; };
Expand Down Expand Up @@ -94,14 +94,14 @@
C9D941D303494C60B0D42452 /* SimpleLineIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = SimpleLineIcons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/SimpleLineIcons.ttf"; sourceTree = "<group>"; };
D16B5A06970DB36EE09E589A /* Pods-HelloWorld.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld.debug.xcconfig"; path = "Target Support Files/Pods-HelloWorld/Pods-HelloWorld.debug.xcconfig"; sourceTree = "<group>"; };
D2E9F9FB75E641BF8ACAF327 /* AntDesign.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = AntDesign.ttf; path = "../node_modules/react-native-vector-icons/Fonts/AntDesign.ttf"; sourceTree = "<group>"; };
D987AA3C470B4B6D8E7B951D /* icomoon.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = icomoon.ttf; path = ../src/components/Icon/fonts/icomoon.ttf; sourceTree = "<group>"; };
DAFA8EA6E5BA432B9A2C1EB2 /* MaterialCommunityIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = MaterialCommunityIcons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/MaterialCommunityIcons.ttf"; sourceTree = "<group>"; };
DB11BE7D1E5F4D4184084058 /* FontAwesome5_Solid.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = FontAwesome5_Solid.ttf; path = "../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Solid.ttf"; sourceTree = "<group>"; };
E299D1654D30617409BC8F5B /* Pods-HelloWorld.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld.release.xcconfig"; path = "Target Support Files/Pods-HelloWorld/Pods-HelloWorld.release.xcconfig"; sourceTree = "<group>"; };
E46430084D55EDB24E875F77 /* Pods-HelloWorld-tvOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld-tvOSTests.debug.xcconfig"; path = "Target Support Files/Pods-HelloWorld-tvOSTests/Pods-HelloWorld-tvOSTests.debug.xcconfig"; sourceTree = "<group>"; };
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; };
F56F8457B82FEE136A5126B7 /* Pods-HelloWorld-HelloWorldTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld-HelloWorldTests.release.xcconfig"; path = "Target Support Files/Pods-HelloWorld-HelloWorldTests/Pods-HelloWorld-HelloWorldTests.release.xcconfig"; sourceTree = "<group>"; };
D987AA3C470B4B6D8E7B951D /* icomoon.ttf */ = {isa = PBXFileReference; name = "icomoon.ttf"; path = "../src/components/Icon/fonts/icomoon.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -235,7 +235,7 @@
83CBBA001A601CBA00E9B192 /* Products */ = {
isa = PBXGroup;
children = (
13B07F961A680F5B00A75B9A /* App Dev.app */,
13B07F961A680F5B00A75B9A /* App Storybook.app */,
00E356EE1AD99517003FC87E /* HelloWorldTests.xctest */,
2D02E47B1E0B4A5D006451C7 /* HelloWorld-tvOS.app */,
2D02E4901E0B4A5D006451C7 /* HelloWorld-tvOSTests.xctest */,
Expand Down Expand Up @@ -302,7 +302,7 @@
);
name = HelloWorld;
productName = HelloWorld;
productReference = 13B07F961A680F5B00A75B9A /* App Dev.app */;
productReference = 13B07F961A680F5B00A75B9A /* App Storybook.app */;
productType = "com.apple.product-type.application";
};
2D02E47A1E0B4A5D006451C7 /* HelloWorld-tvOS */ = {
Expand Down
30 changes: 29 additions & 1 deletion template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@
"aprod": "ENVFILE=.env npx react-native run-android --appId com.app.android --main-activity MainActivity",
"a-dev-signing": "cd android && ENVFILE=.env.dev ./gradlew :app:signingReport",
"a-qa-signing": "cd android && ENVFILE=.env.qa ./gradlew :app:signingReport",
"a-prod-signing": "cd android && ENVFILE=.env ./gradlew :app:signingReport"
"a-prod-signing": "cd android && ENVFILE=.env ./gradlew :app:signingReport",
"prestorybook": "rnstl",
"istorybook": "npx react-native run-ios --simulator='iPhone 11 Pro' --scheme='HelloWorld-storybook'",
"astorybook": "ENVFILE=.env.storybook npx react-native run-android --appId com.android.dev --main-activity MainActivity",
"storybook": "start-storybook -p 7007",
"build-storybook": "build-storybook"
},
"dependencies": {
"@react-native-community/async-storage": "^1.12.1",
Expand Down Expand Up @@ -55,6 +60,13 @@
"@babel/core": "^7.8.4",
"@babel/runtime": "^7.8.4",
"@react-native-community/eslint-config": "^1.1.0",
"@storybook/addon-actions": "^5.3",
"@storybook/addon-knobs": "^5.3",
"@storybook/addon-links": "^5.3",
"@storybook/addon-ondevice-actions": "^5.3.23",
"@storybook/addon-ondevice-knobs": "^5.3.25",
"@storybook/react-native": "^5.3.25",
"@storybook/react-native-server": "^5.3.23",
"@types/jest": "^25.2.3",
"@types/lodash": "^4.14.168",
"@types/react-native": "^0.63.2",
Expand All @@ -65,6 +77,7 @@
"@typescript-eslint/eslint-plugin": "^4.18.0",
"@typescript-eslint/parser": "^4.18.0",
"babel-jest": "^25.1.0",
"babel-loader": "^8.2.2",
"babel-plugin-module-resolver": "^4.1.0",
"eslint": "^6.5.1",
"eslint-config-airbnb-typescript-prettier": "^4.1.0",
Expand All @@ -75,6 +88,8 @@
"eslint-plugin-react-hooks": "^4.2.0",
"jest": "^25.1.0",
"metro-react-native-babel-preset": "^0.59.0",
"react-dom": "16.13.1",
"react-native-storybook-loader": "https://github.com/mthuong/react-native-storybook-loader.git",
"react-test-renderer": "16.13.1",
"reactotron-react-native": "^5.0.0",
"typescript": "^3.8.3"
Expand All @@ -91,6 +106,19 @@
"jsx",
"json",
"node"
],
"setupFilesAfterEnv": [
"<rootDir>/__mocks__/globalMock.ts"
]
},
"config": {
"react-native-storybook-loader": {
"searchDir": [
"./src",
"./storybook"
],
"pattern": "**/*.stories.*",
"outputFile": "storybook/storyLoader.ts"
}
}
}
9 changes: 9 additions & 0 deletions template/src/common/func.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,12 @@ export function injectValue(
export function notEmpty<T>(value: T | null | undefined): value is T {
return value !== null && value !== undefined
}

/**
* Get type-safe lookups
* @param obj
* @param key
*/
export function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key] // Inferred type is T[K]
}
66 changes: 66 additions & 0 deletions template/src/components/Box/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { storiesOf } from '@storybook/react-native'
import { Text } from 'components/Text'
import React from 'react'
import { StyleSheet, View } from 'react-native'
import { Box } from '.'

storiesOf('components/Box', module)
.addDecorator((story) => <View>{story()}</View>)
.add('center', () => (
<Box center>
<Text>center</Text>
</Box>
))
.add('full', () => (
<Box horizontal style={styles.full}>
<Box full style={styles.full1}></Box>
<Box full style={styles.full2}></Box>
</Box>
))
.add('column', () => (
<Box vertical style={styles.full}>
<Box full style={styles.full1}></Box>
<Box full style={styles.full2}></Box>
</Box>
))
.add('row', () => (
<Box horizontal style={styles.full}>
<Box full style={styles.full1}></Box>
<Box full style={styles.full2}></Box>
</Box>
))
.add('padding', () => (
<Box horizontal padding style={styles.full}>
<Box full style={styles.full1}></Box>
<Box full style={styles.full2}></Box>
</Box>
))
.add('paddingV', () => (
<Box horizontal paddingV style={styles.full}>
<Box full style={styles.full1}></Box>
<Box full style={styles.full2}></Box>
</Box>
))
.add('paddingH', () => (
<Box horizontal paddingH style={styles.full}>
<Box full style={styles.full1}></Box>
<Box full style={styles.full2}></Box>
</Box>
))

const styles = StyleSheet.create({
full: {
height: 100,
width: '100%',
backgroundColor: '#eeeeee',
},
full1: {
backgroundColor: 'green',
},
full2: {
backgroundColor: 'yellow',
},
full3: {
backgroundColor: 'grey',
},
})
2 changes: 1 addition & 1 deletion template/src/components/ButtonText/ButtonText.props.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ViewStyle, TextStyle } from 'react-native'
import { TextPresets } from 'components/text'
import { TextPresets } from 'components/Text'
import { ImageAssetTypes } from 'theme/images'

export interface ButtonTextProps {
Expand Down
2 changes: 1 addition & 1 deletion template/src/components/ButtonText/ButtonText.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Image } from 'components/image'
import { Text } from 'components/text'
import { Text } from 'components/Text'
import * as React from 'react'
import { StyleSheet, TouchableOpacity, View } from 'react-native'
import { ButtonTextProps } from './ButtonText.props'
Expand Down
2 changes: 1 addition & 1 deletion template/src/components/Header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import React from 'react'
import { StyleSheet, View } from 'react-native'
import { TouchableOpacity } from 'react-native-gesture-handler'
import { useTheme } from 'theme'
import { Text } from 'components/text'
import { Text } from 'components/Text'
import { IconTypes } from 'components/Icon/types'

type HeaderProps = {
Expand Down
2 changes: 1 addition & 1 deletion template/src/components/TextInput/TextInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
StyleProp,
ViewStyle,
} from 'react-native'
import { Text } from 'components/text'
import { Text } from 'components/Text'
import { Separator } from 'components/modal-picker/components/separator'

export interface InputProps extends TextInputProps {
Expand Down
6 changes: 3 additions & 3 deletions template/src/components/text/text.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as React from 'react'
import React from 'react'
import {
Text as ReactNativeText,
TextProperties,
Expand Down Expand Up @@ -107,10 +107,10 @@ const presets = {
error: { ...styles.BASE, ...fonts.light, color: '#FE3B2F' },
}

type TextPresets = keyof typeof presets
export type TextPresets = keyof typeof presets

const sizes = {
...fontSizes,
}

type TextSizes = keyof typeof sizes
export type TextSizes = keyof typeof sizes
2 changes: 1 addition & 1 deletion template/src/scenes/Authentication/SignIn/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { injectValue } from 'common/func'
import regex from 'common/regex'
import { ButtonText } from 'components/ButtonText'
import { Image } from 'components/image'
import { Text } from 'components/text'
import { Text } from 'components/Text'
import { TextInput } from 'components/TextInput'
import { Formik } from 'formik'
import { useLocalizationContext } from 'localization'
Expand Down
2 changes: 1 addition & 1 deletion template/src/scenes/Authentication/SignUp/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { injectValue } from 'common/func'
import regex from 'common/regex'
import { ButtonText } from 'components/ButtonText'
import { Image } from 'components/image'
import { Text } from 'components/text'
import { Text } from 'components/Text'
import { Formik } from 'formik'
import { useLocalizationContext } from 'localization'
import { strings } from 'localization/strings'
Expand Down
2 changes: 1 addition & 1 deletion template/src/scenes/Authentication/SplashScreen/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react'
import { ActivityIndicator, View, StyleSheet } from 'react-native'
import { Text } from 'components/text'
import { Text } from 'components/Text'

interface Props {
text?: string
Expand Down
2 changes: 1 addition & 1 deletion template/src/scenes/chat/conversations/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { RouteProp } from '@react-navigation/native'
import { StackNavigationProp } from '@react-navigation/stack'
import { Container } from 'components/Container'
import { Header } from 'components/Header'
import { Text } from 'components/text'
import { Text } from 'components/Text'
import { useLocalizationContext } from 'localization'
import { TConversation } from 'scenes/chat/models'
import { RootStackParamList } from 'navigator/Navigator'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Text } from 'components/text'
import { Text } from 'components/Text'
import { TUser, TUserFunc } from 'models'
import React, { useCallback } from 'react'
import { FlatList, TouchableOpacity, View } from 'react-native'
Expand Down
Loading

0 comments on commit 352b0b2

Please sign in to comment.