-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial storybook implementation with example stories and docs
- Loading branch information
1 parent
cafc79d
commit 5751742
Showing
20 changed files
with
1,670 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import React from 'react'; | ||
|
||
import { storiesOf } from '@storybook/react-native'; | ||
import { action } from '@storybook/addon-actions'; | ||
import { text, boolean, select } from '@storybook/addon-knobs'; | ||
|
||
import Alert, { AlertType } from './Alert'; | ||
import Text from './Text'; | ||
import { colors, fontStyles } from ' ../../../styles/common'; | ||
import EvilIcons from 'react-native-vector-icons/EvilIcons'; | ||
|
||
const styles = { | ||
alertIcon: { | ||
fontSize: 20, | ||
...fontStyles.bold, | ||
color: colors.yellow, | ||
marginRight: 6, | ||
}, | ||
}; | ||
|
||
storiesOf('Base / Alert', module) | ||
.addDecorator((getStory) => getStory()) | ||
.add('Default', () => { | ||
const renderIconKnob = boolean('renderIcon', false); | ||
return ( | ||
<Alert | ||
type={select('Type', [AlertType.Info, AlertType.Warning, AlertType.Error], AlertType.Warning)} | ||
small={boolean('small', false)} | ||
renderIcon={renderIconKnob ? () => <EvilIcons name="bell" style={styles.alertIcon} /> : () => null} | ||
onPress={action('onPress')} | ||
> | ||
<Text>{text('children', 'This is an Alert component')}</Text> | ||
</Alert> | ||
); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import React from 'react'; | ||
|
||
import { storiesOf } from '@storybook/react-native'; | ||
import { action } from '@storybook/addon-actions'; | ||
import { text, boolean } from '@storybook/addon-knobs'; | ||
|
||
import Text from './Text'; | ||
|
||
storiesOf('Base / Text', module) | ||
.addDecorator((getStory) => getStory()) | ||
.add('Default', () => ( | ||
<Text | ||
onPress={action('onPress')} | ||
reset={boolean('reset', false)} | ||
centered={boolean('centered', false)} | ||
right={boolean('right', false)} | ||
bold={boolean('bold', false)} | ||
green={boolean('green', false)} | ||
black={boolean('black', false)} | ||
blue={boolean('blue', false)} | ||
grey={boolean('grey', false)} | ||
red={boolean('red', false)} | ||
orange={boolean('orange', false)} | ||
primary={boolean('primary', false)} | ||
disclaimer={boolean('disclaimer', false)} | ||
small={boolean('small', false)} | ||
big={boolean('big', false)} | ||
upper={boolean('upper', false)} | ||
modal={boolean('modal', false)} | ||
infoModal={boolean('infoModal', false)} | ||
link={boolean('link', false)} | ||
strikethrough={boolean('strikethrough', false)} | ||
underline={boolean('underline', false)} | ||
noMargin={boolean('noMargin', false)} | ||
> | ||
{text('children', 'This is a Text component')} | ||
</Text> | ||
)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import React from 'react'; | ||
|
||
import { storiesOf } from '@storybook/react-native'; | ||
import { action } from '@storybook/addon-actions'; | ||
import { text, boolean } from '@storybook/addon-knobs'; | ||
|
||
import Title from './Title'; | ||
|
||
storiesOf('Base / Title', module) | ||
.addDecorator((getStory) => getStory()) | ||
.add('Default', () => ( | ||
<Title onPress={action('onPress')} centered={boolean('centered', false)} hero={boolean('hero', false)}> | ||
{text('children', 'This is a Title component')} | ||
</Title> | ||
)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import React from 'react'; | ||
|
||
import { storiesOf } from '@storybook/react-native'; | ||
import { boolean } from '@storybook/addon-knobs'; | ||
|
||
import Fox from '.'; | ||
import backgroundShapes from '../Swaps/components/LoadingAnimation/backgroundShapes'; | ||
|
||
const customStyle = ` | ||
#head { | ||
height: 30%; | ||
top: 50%; | ||
transform: translateY(-50%); | ||
} | ||
#bgShapes { | ||
position: absolute; | ||
left: 50%; | ||
top: 50%; | ||
width: 70%; | ||
height: 70%; | ||
transform: translateX(-50%) translateY(-50%) rotate(0deg); | ||
animation: rotate 50s linear infinite; | ||
} | ||
@keyframes rotate { | ||
to { | ||
transform: translateX(-50%) translateY(-50%) rotate(360deg); | ||
} | ||
} | ||
`; | ||
storiesOf('UI / Fox', module) | ||
.addDecorator((getStory) => getStory()) | ||
.add('Default', () => { | ||
const customContentKnob = boolean('customContent', false); | ||
return <Fox customContent={customContentKnob ? backgroundShapes : ''} customStyle={customStyle} />; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import React from 'react'; | ||
import { View } from 'react-native'; | ||
import { action } from '@storybook/addon-actions'; | ||
import { text, boolean, select } from '@storybook/addon-knobs'; | ||
import { storiesOf } from '@storybook/react-native'; | ||
import StyledButton from '.'; | ||
|
||
storiesOf('UI / StyledButton', module) | ||
.addDecorator((getStory) => getStory()) | ||
.add('Default', () => ( | ||
<View> | ||
<StyledButton | ||
type={select( | ||
'type', | ||
{ | ||
orange: 'orange', | ||
blue: 'blue', | ||
confirm: 'confirm', | ||
normal: 'normal', | ||
'rounded-normal': 'rounded-normal', | ||
cancel: 'cancel', | ||
signingCancel: 'signingCancel', | ||
transparent: 'transparent', | ||
'transparent-blue': 'transparent-blue', | ||
warning: 'warning', | ||
'warning-empty': 'warning-empty', | ||
info: 'info', | ||
neutral: 'neutral', | ||
danger: 'danger', | ||
sign: 'sign', | ||
view: 'view', | ||
}, | ||
'confirm' | ||
)} | ||
onPress={action('onPress')} | ||
disabled={boolean('disabled', false)} | ||
onPressOut={action('onPressOut')} | ||
> | ||
{text('children', 'Confirm')} | ||
</StyledButton> | ||
</View> | ||
)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,7 +45,8 @@ | |
"sourcemaps:ios": "node_modules/.bin/react-native bundle --platform ios --entry-file index.js --dev false --reset-cache --bundle-output /tmp/bundle.ios.js --assets-dest /tmp/ --sourcemap-output sourcemaps/ios/index.js.map", | ||
"stacktrace:android": "stack-beautifier sourcemaps/android/index.js.map -t sourcemaps/trace.txt", | ||
"stacktrace:ios": "stack-beautifier sourcemaps/ios/index.js.map -t sourcemaps/trace.txt", | ||
"update-changelog": "./scripts/auto-changelog.sh" | ||
"update-changelog": "./scripts/auto-changelog.sh", | ||
"prestorybook": "rnstl" | ||
}, | ||
"prettier": { | ||
"printWidth": 120, | ||
|
@@ -246,6 +247,12 @@ | |
"@metamask/eslint-config-typescript": "^7.0.0", | ||
"@metamask/mobile-provider": "^2.1.0", | ||
"@react-native-community/eslint-config": "^2.0.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", | ||
"@types/enzyme": "^3.10.9", | ||
"@types/jest": "^27.0.1", | ||
"@types/react": "^17.0.11", | ||
|
@@ -258,6 +265,7 @@ | |
"babel-core": "7.0.0-bridge.0", | ||
"babel-eslint": "10.1.0", | ||
"babel-jest": "^26.6.3", | ||
"babel-loader": "^8.2.3", | ||
"concat-cli": "4.0.0", | ||
"detox": "19.4.0", | ||
"enzyme": "3.9.0", | ||
|
@@ -283,6 +291,7 @@ | |
"prettier": "^2.2.1", | ||
"react-dom": "16.8.4", | ||
"react-native-cli": "2.0.1", | ||
"react-native-storybook-loader": "^2.0.4", | ||
"react-native-svg-asset-plugin": "^0.5.0", | ||
"react-redux-test": "npm:[email protected]", | ||
"react-test-renderer": "17.0.2", | ||
|
@@ -291,6 +300,15 @@ | |
"stack-beautifier": "1.0.2", | ||
"typescript": "^4.4.2" | ||
}, | ||
"config": { | ||
"react-native-storybook-loader": { | ||
"searchDir": [ | ||
"./app/components" | ||
], | ||
"pattern": "**/*.stories.@(js|tsx)", | ||
"outputFile": "./storybook/storyLoader.js" | ||
} | ||
}, | ||
"detox": { | ||
"configurations": { | ||
"ios.sim.debug": { | ||
|
@@ -378,7 +396,8 @@ | |
"web3-bzz": false, | ||
"bufferutil": false, | ||
"utf-8-validate": false, | ||
"web3-shh": false | ||
"web3-shh": false, | ||
"highlight.js": false | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
# Documentation Guidelines | ||
|
||
## General Guidelines | ||
|
||
Thorough documentation makes it much easier for a component to be found, adapted and reused. It also provides space for explanation and reasoning for a component. This is useful as components become more complex. | ||
|
||
## Using React Native Storybook | ||
|
||
The below steps will explain how to use Storybook for React Native with our current set up. | ||
|
||
In the React Native Storybook [Getting Started](https://github.com/storybookjs/react-native/tree/v5.3.25#getting-started) guide they suggest you change the default export to the storybook UI. This doesn't have the greatest developer experience and we will improve this in future([see other ways to render storybook](https://github.com/storybookjs/react-native/tree/v5.3.25#other-ways-to-render-storybook)) but for now: | ||
|
||
**Prerequisite** | ||
Make sure you have your environment set up first. To do that follow the set up instructions in the main [README.md](https://github.com/MetaMask/metamask-mobile) | ||
|
||
1. In the root `./index.js` file comment out `AppRegistry.registerComponent(name, () => Root);` and add: | ||
|
||
``` | ||
export { default } from "./storybook"; | ||
``` | ||
|
||
this will replace the entry point of the app with storybook. | ||
|
||
2. Once you have replaced the entry point of the app with storybook in `./index.js` run | ||
|
||
``` | ||
yarn watch | ||
``` | ||
|
||
3. Open a new terminal window and run | ||
|
||
``` | ||
yarn start:ios | ||
``` | ||
|
||
Once the app builds you should be greeted with this screen. | ||
|
||
![React Native Storybook Preview](./images/rn.sb.1.png) | ||
|
||
To view all of the stories open the navigator | ||
|
||
![Storybook Navigator](./images/rn.sb.2.png) | ||
|
||
Select a story to preview | ||
|
||
![Storybook Navigator](./images/rn.sb.3.png) | ||
|
||
You should also be able to use storybook plugins including actions and knobs in the addons tab | ||
|
||
![Storybook Plugins](./images/rn.sb.4.png) | ||
|
||
## Creating a Story | ||
|
||
1. Create a `ComponentName.stories.tsx` file (example `Alert` story below) | ||
2. Run `yarn prestorybook` (Uses [storybook loader](https://github.com/elderfo/react-native-storybook-loader) to automatically find `stories.@(js|tsx)`(javascript or typescript) files **required step after every new story file is created**) | ||
|
||
Example `Alert` story | ||
|
||
```jsx | ||
// app/components/Base/Alert.stories.tsx | ||
|
||
// Import react | ||
import React from 'react'; | ||
|
||
// Import storybook functions and plugins | ||
import { storiesOf } from '@storybook/react-native'; | ||
import { action } from '@storybook/addon-actions'; | ||
import { text, boolean, select } from '@storybook/addon-knobs'; | ||
|
||
// Import the component and any supplementary components / styles that will help with documentation / interactivity | ||
import Alert, { AlertType } from './Alert'; | ||
import Text from './Text'; | ||
import { colors, fontStyles } from ' ../../../styles/common'; | ||
import EvilIcons from 'react-native-vector-icons/EvilIcons'; | ||
|
||
// Add any styles that are needed | ||
const styles = { | ||
alertIcon: { | ||
fontSize: 20, | ||
...fontStyles.bold, | ||
color: colors.yellow, | ||
marginRight: 6, | ||
}, | ||
}; | ||
|
||
// Create story using the component directory and name for the title | ||
storiesOf('Base / Alert', module) | ||
.addDecorator((getStory) => getStory()) | ||
// The naming convention for a component's the first story should be "Default" | ||
.add('Default', () => { | ||
const renderIconKnob = boolean('renderIcon', false); | ||
return ( | ||
<Alert | ||
// All appropriate props should include an action or knob to show component api options | ||
type={select('Type', [AlertType.Info, AlertType.Warning, AlertType.Error], AlertType.Warning)} | ||
small={boolean('small', false)} | ||
renderIcon={renderIconKnob ? () => <EvilIcons name="bell" style={styles.alertIcon} /> : () => null} | ||
onPress={action('onPress')} | ||
> | ||
<Text>{text('children', 'This is an Alert component')}</Text> | ||
</Alert> | ||
); | ||
}); | ||
``` | ||
|
||
Nice work! You're now ready to start creating component documentation using storybook 🎉 👍 | ||
|
||
> Note: Currently React Native Storybook is at v5.3 hoping to upgrade to [v6](https://github.com/storybookjs/react-native/blob/next-6.0/v6README.md) soon.. |
Oops, something went wrong.