Skip to content

Latest commit

History

History
202 lines (133 loc) 路 4.29 KB

MANUAL_SETUP.md

File metadata and controls

202 lines (133 loc) 路 4.29 KB

Setup for v7 React Native Storybook

Before getting into the guide consider using a template for a simpler setup process.

Prebuilt Templates:

For expo you can use this template with the following command

npx create-expo-app --template expo-template-storybook AwesomeStorybook

For react native cli you can use this template

npx react-native init MyApp --template react-native-template-storybook

Manual setup

You may wish to setup everything yourself, you can use the following guide to do so.

Install dependencies

Expo

expo install @storybook/react-native @react-native-async-storage/async-storage react-dom react-native-safe-area-context

React native CLI

yarn add -D @storybook/react-native @react-native-async-storage/async-storage react-native-safe-area-context react-dom

IOS

If running on an IOS device with rn cli make sure to run pod install first

cd ios; pod install; cd ..;

Configuration

.storybook

Create a folder called .storybook with files: main.ts, preview.tsx, index.tsx

You can use this one-liner to quickly create those files:

mkdir .storybook && touch .storybook/main.ts .storybook/preview.tsx .storybook/index.tsx

.storybook/main.ts

import { StorybookConfig } from '@storybook/react-native';

const main: StorybookConfig = {
  stories: ['../components/**/*.stories.?(ts|tsx|js|jsx)'],
  addons: [],
};

export default main;

.storybook/preview.tsx

import type { Preview } from '@storybook/react';

const preview: Preview = {
  parameters: {},
  decorators: [],
};

export default preview;

package.json

Add the following to the scripts in your package.json.

{
  "scripts": {
    "storybook-generate": "sb-rn-get-stories"
  }
}

generate storybook.requires.ts

run yarn storybook-generate

.storybook/index.tsx

import { view } from './storybook.requires';
import AsyncStorage from '@react-native-async-storage/async-storage';

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

export default StorybookUIRoot;

metro.config.js

Update your metro config to enable transformer.unstable_allowRequireContext

Expo

First create metro config file if you don't have it yet.

npx expo customize metro.config.js

Then set transformer.unstable_allowRequireContext to true

const { getDefaultConfig } = require('expo/metro-config');

const { generate } = require('@storybook/react-native/scripts/generate');

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

const defaultConfig = getDefaultConfig(__dirname);

defaultConfig.transformer.unstable_allowRequireContext = true;

module.exports = defaultConfig;

React native

const { generate } = require('@storybook/react-native/scripts/generate');

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

module.exports = {
  /* existing config */
  transformer: {
    unstable_allowRequireContext: true,
  },
};

Add a stories file

In the main.ts we created the path was set as ../components/\*_/_.stories.?(ts|tsx|js|jsx) which matches any .stories file inside the components folder.

Create a file called Button.stories.tsx in the components folder.

import type { Meta, StoryObj } from '@storybook/react';
import { Button } from 'react-native';

const meta = {
  title: 'React Native Button',
  component: Button,
} satisfies Meta<typeof Button>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Basic: Story = {
  args: {
    title: 'Hello world',
  },
};

This is a simple example you can do more by adding addons and exploring more features of storybook.

Render Storybook

The only thing left to do is return Storybook's UI in your app entry point (such as App.tsx) like this:

export { default } from './.storybook';

If you want to be able to swap easily between storybook and your app, have a look at this blog post

Run storybook

Then you can run yarn ios or yarn android to run the app like normal.