Skip to content

Commit

Permalink
feat: [ZN-188] Add storybook
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielMarkiel authored Apr 18, 2024
1 parent a6c2819 commit fca425a
Show file tree
Hide file tree
Showing 14 changed files with 1,898 additions and 25 deletions.
4 changes: 0 additions & 4 deletions .github/workflows/e2e_android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,12 @@ jobs:
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Setup Gradle
uses: gradle/gradle-build-action@v3

- name: Install dependencies
run: yarn --frozen-lockfile

- name: Setup Java
uses: actions/setup-java@v3
with:
cache: gradle
distribution: temurin
java-version: 17

Expand Down
11 changes: 11 additions & 0 deletions .storybook/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import { view } from './storybook.requires';

const StorybookUIRoot = view.getStorybookUI({
storage: {
getItem: AsyncStorage.getItem,
setItem: AsyncStorage.setItem,
},
});

export default StorybookUIRoot;
8 changes: 8 additions & 0 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { StorybookConfig } from '@storybook/react-native';

const main: StorybookConfig = {
stories: ['../src/components/**/*.stories.?(ts|tsx|js|jsx)'],
addons: ['@storybook/addon-ondevice-controls', '@storybook/addon-ondevice-actions'],
};

export default main;
24 changes: 24 additions & 0 deletions .storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { Preview } from '@storybook/react';
import React from 'react';

import { AppProviders } from '../src/providers/AppProviders';

const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
},
decorators: [
(Story) => (
<AppProviders>
<Story />
</AppProviders>
),
],
};

export default preview;
61 changes: 61 additions & 0 deletions .storybook/storybook.requires.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/* do not change this file, it is auto generated by storybook. */

import {
start,
prepareStories,
getProjectAnnotations,
} from "@storybook/react-native";

import "@storybook/addon-ondevice-controls/register";
import "@storybook/addon-ondevice-actions/register";

const normalizedStories = [
{
titlePrefix: "",
directory: "./src/components",
files: "**/*.stories.?(ts|tsx|js|jsx)",
importPathMatcher:
/^\.(?:(?:^|\/|(?:(?:(?!(?:^|\/)\.).)*?)\/)(?!\.)(?=.)[^/]*?\.stories\.(?:ts|tsx|js|jsx)?)$/,
// @ts-ignore
req: require.context(
"../src/components",
true,
/^\.(?:(?:^|\/|(?:(?:(?!(?:^|\/)\.).)*?)\/)(?!\.)(?=.)[^/]*?\.stories\.(?:ts|tsx|js|jsx)?)$/
),
},
];

declare global {
var view: ReturnType<typeof start>;
var STORIES: typeof normalizedStories;
}

const annotations = [
require("./preview"),
require("@storybook/react-native/dist/preview"),
require("@storybook/addon-actions/preview"),
];

global.STORIES = normalizedStories;

// @ts-ignore
module?.hot?.accept?.();

if (!global.view) {
global.view = start({
annotations,
storyEntries: normalizedStories,
});
} else {
const { importMap } = prepareStories({ storyEntries: normalizedStories });

global.view._preview.onStoriesChanged({
importFn: async (importPath: string) => importMap[importPath],
});

global.view._preview.onGetProjectAnnotationsChanged({
getProjectAnnotations: getProjectAnnotations(global.view, annotations),
});
}

export const view = global.view;
9 changes: 8 additions & 1 deletion App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,11 @@ const App = () => {
);
};

export default App;
let AppEntryPoint = App;

if (process.env.STORYBOOK_ENABLED === 'true') {
// eslint-disable-next-line @typescript-eslint/no-var-requires
AppEntryPoint = require('./.storybook').default;
}

export default AppEntryPoint;
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,18 @@ You can read more about the react navigation at: https://reactnavigation.org/doc

### AppCenter

- Environment variables need to have `RN_` prefix. For example if your variable is `BACKEND_URL`(in `.env` file) it should be added as `RN_BACKEND_URL` to the App Center.
- Environment variables need to have `RN_` prefix. For example if your variable is `BACKEND_URL`(in `.env` file) it
should be added as `RN_BACKEND_URL` to the App Center.

## Storybook

To open storybook:

1. Start metro bundler using `yarn storybook`
1. Run ios/android build using `yarn ios` or `yarn android`

## Troubleshooting

### Changes in .env file are not reflected in ios application even after rebuild

To see the latest changes you may need to run `cd ios && pod install` and then rebuild the project.
To see the latest changes you may need to run `cd ios && pod install` and then rebuild the project.
6 changes: 6 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ module.exports = {
},
],
'nativewind/babel',
[
'transform-inline-environment-variables',
{
include: ['NODE_ENV', 'STORYBOOK_ENABLED'],
},
],
'react-native-reanimated/plugin',
],
};
20 changes: 20 additions & 0 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,10 @@ PODS:
- React-Core
- react-native-safe-area-context (4.7.4):
- React-Core
- react-native-slider (4.5.2):
- glog
- RCT-Folly (= 2022.05.16.00)
- React-Core
- React-nativeconfig (0.73.6)
- React-NativeModulesApple (0.73.6):
- glog
Expand Down Expand Up @@ -1123,6 +1127,10 @@ PODS:
- React-jsi (= 0.73.6)
- React-logger (= 0.73.6)
- React-perflogger (= 0.73.6)
- RNCAsyncStorage (1.23.1):
- React-Core
- RNDateTimePicker (7.6.4):
- React-Core
- RNGestureHandler (2.14.0):
- glog
- RCT-Folly (= 2022.05.16.00)
Expand Down Expand Up @@ -1195,6 +1203,7 @@ DEPENDENCIES:
- react-native-config (from `../node_modules/react-native-config`)
- react-native-mmkv (from `../node_modules/react-native-mmkv`)
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- "react-native-slider (from `../node_modules/@react-native-community/slider`)"
- React-nativeconfig (from `../node_modules/react-native/ReactCommon`)
- React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`)
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
Expand All @@ -1215,6 +1224,8 @@ DEPENDENCIES:
- React-runtimescheduler (from `../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`)
- React-utils (from `../node_modules/react-native/ReactCommon/react/utils`)
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
- "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)"
- "RNDateTimePicker (from `../node_modules/@react-native-community/datetimepicker`)"
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
- RNReanimated (from `../node_modules/react-native-reanimated`)
- RNScreens (from `../node_modules/react-native-screens`)
Expand Down Expand Up @@ -1300,6 +1311,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-mmkv"
react-native-safe-area-context:
:path: "../node_modules/react-native-safe-area-context"
react-native-slider:
:path: "../node_modules/@react-native-community/slider"
React-nativeconfig:
:path: "../node_modules/react-native/ReactCommon"
React-NativeModulesApple:
Expand Down Expand Up @@ -1340,6 +1353,10 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/react/utils"
ReactCommon:
:path: "../node_modules/react-native/ReactCommon"
RNCAsyncStorage:
:path: "../node_modules/@react-native-async-storage/async-storage"
RNDateTimePicker:
:path: "../node_modules/@react-native-community/datetimepicker"
RNGestureHandler:
:path: "../node_modules/react-native-gesture-handler"
RNReanimated:
Expand Down Expand Up @@ -1394,6 +1411,7 @@ SPEC CHECKSUMS:
react-native-config: 86038147314e2e6d10ea9972022aa171e6b1d4d8
react-native-mmkv: e97c0c79403fb94577e5d902ab1ebd42b0715b43
react-native-safe-area-context: 2cd91d532de12acdb0a9cbc8d43ac72a8e4c897c
react-native-slider: 7a39874fc1fcdfee48e448fa72cce0a8f2c7c5d6
React-nativeconfig: b4d4e9901d4cabb57be63053fd2aa6086eb3c85f
React-NativeModulesApple: cd26e56d56350e123da0c1e3e4c76cb58a05e1ee
React-perflogger: 5f49905de275bac07ac7ea7f575a70611fa988f2
Expand All @@ -1414,6 +1432,8 @@ SPEC CHECKSUMS:
React-runtimescheduler: 9636eee762c699ca7c85751a359101797e4c8b3b
React-utils: d16c1d2251c088ad817996621947d0ac8167b46c
ReactCommon: 2aa35648354bd4c4665b9a5084a7d37097b89c10
RNCAsyncStorage: 826b603ae9c0f88b5ac4e956801f755109fa4d5c
RNDateTimePicker: 08f00a2c341bf96e4b30da15799fbdd4c5fa48a3
RNGestureHandler: a4c4561307e67f2942f5a4fe1526ff78cf3f5280
RNReanimated: dee37576492f1a375017515f5c77e66e5eec696b
RNScreens: 17e2f657f1b09a71ec3c821368a04acbb7ebcb46
Expand Down
14 changes: 13 additions & 1 deletion metro.config.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
const { generate } = require('@storybook/react-native/scripts/generate');

const path = require('path');

generate({
configPath: path.resolve(__dirname, './.storybook'),
});

/**
* Metro configuration
* https://facebook.github.io/metro/docs/configuration
*
* @type {import('metro-config').MetroConfig}
*/
const config = {};
const config = {
transformer: {
// Required by Storybook
unstable_allowRequireContext: true,
},
};

module.exports = mergeConfig(getDefaultConfig(__dirname), config);
10 changes: 10 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
"lint": "tsc && eslint . --ext .js,.jsx,.ts,.tsx",
"postinstall": "npx patch-package",
"clean": "react-native clean --include android,cocoapods,metro,npm,watchman,yarn",
"storybook": "STORYBOOK_ENABLED=true yarn start-cache",
"storybook-generate": "sb-rn-get-stories",
"e2e:build-android-debug": "ENVFILE=.env.e2e detox build -c android.emu.debug",
"e2e:build-android-release": "ENVFILE=.env.e2e detox build -c android.emu.release",
"e2e:run-android-debug": "detox test -c android.emu.debug",
Expand Down Expand Up @@ -46,10 +48,16 @@
"@babel/core": "^7.23.2",
"@babel/preset-env": "^7.23.2",
"@babel/runtime": "^7.23.2",
"@react-native-async-storage/async-storage": "^1.23.1",
"@react-native-community/datetimepicker": "^7.6.4",
"@react-native-community/slider": "^4.5.2",
"@react-native/babel-preset": "0.73.21",
"@react-native/eslint-config": "0.73.2",
"@react-native/metro-config": "0.73.5",
"@react-native/typescript-config": "0.73.1",
"@storybook/addon-ondevice-actions": "^7.6.17",
"@storybook/addon-ondevice-controls": "^7.6.17",
"@storybook/react-native": "^7.6.17",
"@testing-library/jest-native": "^5.4.3",
"@testing-library/react-native": "^12.3.0",
"@tsconfig/react-native": "^3.0.2",
Expand All @@ -61,6 +69,7 @@
"@types/react-test-renderer": "^18.0.3",
"babel-jest": "^29.7.0",
"babel-plugin-module-resolver": "^5.0.0",
"babel-plugin-transform-inline-environment-variables": "^0.4.4",
"detox": "^20.20.2",
"eslint": "^8.19.0",
"eslint-config-prettier": "^8.3.0",
Expand All @@ -70,6 +79,7 @@
"jest": "^29.7.0",
"msw": "2.2.13",
"prettier": "2.8.8",
"react-dom": "18.2.0",
"react-test-renderer": "18.2.0",
"tailwindcss": "3.3.2",
"ts-jest": "^29.1.1",
Expand Down
34 changes: 34 additions & 0 deletions src/components/Button/Button.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { Meta, StoryObj } from '@storybook/react';
import { View } from 'react-native';

import Button from './Button';

const ButtonMeta: Meta<typeof Button> = {
title: 'Button',
component: Button,
argTypes: {
onPress: { action: 'pressed the button' },
},
args: {
label: 'Hello world',
disabled: false,
},
decorators: [
(Story) => (
// eslint-disable-next-line react-native/no-inline-styles
<View style={{ alignItems: 'center', justifyContent: 'center', flex: 1 }}>
<Story />
</View>
),
],
};

export default ButtonMeta;

export const Basic: StoryObj<typeof Button> = {};

export const AnotherExample: StoryObj<typeof Button> = {
args: {
label: 'Another example',
},
};
27 changes: 27 additions & 0 deletions src/components/Translation/Translation.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { Meta, StoryObj } from '@storybook/react';
import { View } from 'react-native';

import { Translation } from './Translation';

const TranslationMeta: Meta<typeof Translation> = {
title: 'Translation',
component: Translation,
args: {
id: 'home.helloWorld',
values: {
name: 'Joe',
},
},
decorators: [
(Story) => (
// eslint-disable-next-line react-native/no-inline-styles
<View style={{ alignItems: 'center', justifyContent: 'center', flex: 1 }}>
<Story />
</View>
),
],
};

export default TranslationMeta;

export const Basic: StoryObj<typeof Translation> = {};
Loading

0 comments on commit fca425a

Please sign in to comment.