-
-
-You can use Storybook to test and share your component library quickly and easily! This example shows how to use Expo modules with Storybook CLI and Expo CLI.
+You can use Storybook to test and share your component library quickly and easily! This example shows how to use Expo libraries with Storybook CLI and Webpack.
## Running with Storybook CLI
-![expo web with storybook-cli](https://i.imgur.com/0x0Ecmp.png "expo web with storybook-cli")
+> web only / Webpack
-> web only
+This system uses the [community react-native-web addon](https://github.com/storybookjs/addon-react-native-web/) to configure Storybook's Webpack config to support running React Native for web.
-This method runs your Expo components in a Storybook-React environment. This is different to Expo web, but may prove helpful as the Storybook-React community is more robust than the Storybook-React Native community.
+This method runs your Expo components in a Storybook-React environment. This is different to Expo CLI's Webpack config.
-- Create Expo project `expo init my-project`
+- Create Expo project `npx create expo my-project`
- You can use any template, we'll use the managed blank TypeScript project for this example.
-- `cd` into the project and run `npx -p @storybook/cli sb init --type react` to bootstrap a new React project
-- Install the expo webpack config so we can add unimodules support `yarn add -D @expo/webpack-config`
-- Create a [custom webpack config](./.storybook/webpack.config.js) `touch .storybook/webpack.config.js`
-
- ```js
- const { resolve } = require("path");
- const { withUnimodules } = require("@expo/webpack-config/addons");
-
- module.exports = ({ config }) => {
- return withUnimodules(config, { projectRoot: resolve(__dirname, "../") });
- };
- ```
-
+- `cd` into the project and run `npx sb init --type react`, and select Webpack 5 to bootstrap a new React project.
+- Install the requisite dependencies `npx expo add react-dom react-native-web @storybook/addon-react-native-web expo-pwa`
+- The contents of `.storybook/main.js` have been modified to support loading the Expo config for the `expo-constants` libraries.
- Run `yarn build-storybook` to try it out!
- The example should open to `http://localhost:6006/`
-- You may also want to add `storybook-static` to your `.gitignore`
-
-### 📁 File Structure
-
-```
-Expo with Storybook CLI
-├── stories
-│ └── Example.stories.js ➡️ A Storybook page to render
-├── .storybook
-│ ├── config.js ➡️ The entry point / config for a typical Storybook project.
-│ └── webpack.config.js ➡️ The custom Webpack config used to add Expo support to Storybook CLI.
-├── assets ➡️ All static assets for your project
-├── storybook-static ➡️ Generated Storybook files (should be ignored)
-└── babel.config.js ➡️ Babel config (should be using `babel-preset-expo`)
-```
-
-## Running with Expo CLI
-
-
-
-> This method is universal :]
-
-This project can be used for iOS, Android, and web! You may find that it's better to use it for native only, and to use the "Running with Storybook" method for web. Unlike the Expo + Next.js flow, you can use both web methods at the same time!
-
-- Create Expo project `expo init my-project`
- - You can use any template, we'll use the managed blank TypeScript project for this example.
-- `cd` into the project and run `npx -p @storybook/cli sb init --type react` to bootstrap a new React project.
-- Install the Storybook React Native package:
- - `yarn add -D @storybook/react-native`
-- In your `App.tsx` or `App.js`
-
-```ts
-import { configure, getStorybookUI } from "@storybook/react-native";
-
-configure(() => {
- // Since require.context doesn't exist in metro bundler world, we have to
- // manually import files ending in *.stories.js
- require("./stories");
-}, module);
-
-export default getStorybookUI();
-```
-
-- Create a file for importing all of the stories ([`stories/index.js`](./stories/index.js)):
-
- - `touch stories/index.js`
- - Import all of your stories in this file. Ex:
-
- ```js
- // stories/index.js
- import "./1-Button.stories";
- ```
-
-- Register your stories for React Native:
-
-```diff
-// Example.stories.js
-+ import { storiesOf } from '@storybook/react-native';
-
-export const text = () => ( /_ Example JSX _/ );
-
-// Register your story with the `module`, name, and React functional component.
-
-+ storiesOf('Button', module).add('Text', text);
-
-```
-
-- Now run `yarn start` or `npm run start` to see it in action!
-
-### 📁 File Structure
-
-```
-Storybook with Expo CLI
-├── stories
-│ ├── index.js ➡️ Native story imports
-│ └── Example.stories.js ➡️ A Storybook page to render
-├── assets ➡️ All static assets for your project
-├── App.tsx ➡️ Entry Point for universal Expo apps
-├── app.config.js ➡️ Expo config file
-└── babel.config.js ➡️ Babel config (should be using `babel-preset-expo`)
-```
-
-## 📝 Notes
-- [Storybook React](https://storybook.js.org/docs/react/get-started/introduction)
-- [Storybook React Native](https://storybook.js.org/docs/guides/guide-react-native/)
+To learn more, configure the Storybook plugin according to [the official guide](https://github.com/storybookjs/addon-react-native-web/).
diff --git a/with-storybook/assets/retro-regular.ttf b/with-storybook/assets/retro-regular.ttf
deleted file mode 100755
index 15bb923c..00000000
Binary files a/with-storybook/assets/retro-regular.ttf and /dev/null differ
diff --git a/with-storybook/package.json b/with-storybook/package.json
index 0d798213..7cf558d0 100644
--- a/with-storybook/package.json
+++ b/with-storybook/package.json
@@ -1,31 +1,31 @@
{
"scripts": {
- "start": "expo start",
- "web": "start-storybook -p 6006",
- "build-storybook": "build-storybook"
+ "storybook": "storybook dev -p 6006",
+ "build-storybook": "storybook build"
},
"dependencies": {
- "expo": "^49.0.3",
- "expo-constants": "~14.4.2",
- "expo-font": "~11.4.0",
- "expo-linear-gradient": "~12.3.0",
+ "expo": "~49.0.13",
+ "expo-linear-gradient": "^12.5.0",
+ "expo-status-bar": "~1.6.0",
"react": "18.2.0",
- "react-dom": "18.2.0",
- "react-native": "0.72.3",
+ "react-native": "0.72.5",
"react-native-web": "~0.19.6"
},
"devDependencies": {
- "@babel/core": "^7.19.3",
- "@expo/webpack-config": "^18.0.1",
- "@storybook/addon-actions": "~5.2.1",
- "@storybook/addon-links": "~5.2.1",
- "@storybook/addons": "~5.2.1",
- "@storybook/react": "~5.2.1",
- "@storybook/react-native": "~5.3.19",
- "@types/react": "~18.2.14",
- "@types/react-dom": "~18.0.8",
- "@types/react-native": "~0.70.6",
- "babel-loader": "^8.0.6",
- "typescript": "^5.1.3"
- }
+ "expo-pwa": "^0.0.127",
+ "@storybook/addon-react-native-web": "^0.0.21",
+ "@babel/core": "^7.20.0",
+ "@storybook/addon-essentials": "^7.4.6",
+ "@storybook/addon-interactions": "^7.4.6",
+ "@storybook/addon-links": "^7.4.6",
+ "@storybook/addon-onboarding": "^1.0.8",
+ "@storybook/blocks": "^7.4.6",
+ "@storybook/react": "^7.4.6",
+ "@storybook/react-webpack5": "^7.4.6",
+ "@storybook/testing-library": "^0.2.2",
+ "prop-types": "^15.8.1",
+ "react-dom": "18.2.0",
+ "storybook": "^7.4.6"
+ },
+ "private": true
}
diff --git a/with-storybook/stories/0-Welcome.stories.js b/with-storybook/stories/0-Welcome.stories.js
deleted file mode 100644
index dda9c77b..00000000
--- a/with-storybook/stories/0-Welcome.stories.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import React from 'react';
-import { linkTo } from '@storybook/addon-links';
-import { storiesOf } from '@storybook/react-native';
-import { Welcome } from '@storybook/react/demo';
-
-export default {
- title: 'Welcome',
-};
-
-export const toStorybook = () => ;
-
-toStorybook.story = {
- name: 'to Storybook',
-};
-
-// On-Device Register
-storiesOf('Welcome', module).add(toStorybook.story.name, toStorybook);
diff --git a/with-storybook/stories/1-Button.stories.js b/with-storybook/stories/1-Button.stories.js
deleted file mode 100644
index 661a490e..00000000
--- a/with-storybook/stories/1-Button.stories.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import React from 'react';
-import { action } from '@storybook/addon-actions';
-import { storiesOf } from '@storybook/react-native';
-import { Button } from 'react-native';
-
-export default {
- title: 'Button',
-};
-
-export const text = () => (
-
-);
-
-// On-Device Register
-storiesOf('Button', module).add('Text', text);
diff --git a/with-storybook/stories/2-Constants.stories.js b/with-storybook/stories/2-Constants.stories.js
deleted file mode 100644
index 6600d6ff..00000000
--- a/with-storybook/stories/2-Constants.stories.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import React from 'react';
-import { storiesOf } from '@storybook/react-native';
-import Constants from 'expo-constants';
-import { Text } from 'react-native';
-
-export default {
- title: 'Constants',
-};
-
-export const constants = () => (
- {JSON.stringify(Constants, null, 2)}
-);
-
-// On-Device Register
-storiesOf('Constants', module).add('Constants', constants);
diff --git a/with-storybook/stories/3-LinearGradient.stories.js b/with-storybook/stories/3-LinearGradient.stories.js
deleted file mode 100644
index 4c77c2bf..00000000
--- a/with-storybook/stories/3-LinearGradient.stories.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import React from 'react';
-import { storiesOf } from '@storybook/react-native';
-import { LinearGradient } from 'expo-linear-gradient';
-
-export default {
- title: 'LinearGradient',
-};
-
-export const linearGradient = () => (
-
-);
-
-// On-Device Register
-storiesOf('LinearGradient', module).add('Linear Gradient', linearGradient);
diff --git a/with-storybook/stories/4-Font.stories.js b/with-storybook/stories/4-Font.stories.js
deleted file mode 100644
index b8899576..00000000
--- a/with-storybook/stories/4-Font.stories.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import React, { useEffect, useState } from 'react';
-import { storiesOf } from '@storybook/react-native';
-import * as Font from 'expo-font';
-import { Text } from 'react-native';
-
-export default {
- title: 'Font',
-};
-
-export const CustomFontComponent = () => {
- const [loaded, setLoaded] = useState(false);
-
- useEffect(() => {
- (async () => {
- await Font.loadAsync({
- 'retro-regular': require('../assets/retro-regular.ttf')
- });
- setLoaded(true);
- })();
- }, []);
-
- return (
- loaded && (
-
- Cool new font
-
- )
- );
-}
-
-// On-Device Register
-storiesOf('Font', module).add('Font', () => ());
diff --git a/with-storybook/stories/Button.jsx b/with-storybook/stories/Button.jsx
new file mode 100644
index 00000000..2db9b6b1
--- /dev/null
+++ b/with-storybook/stories/Button.jsx
@@ -0,0 +1,59 @@
+import React from "react";
+import PropTypes from "prop-types";
+import { Pressable, Text } from "react-native";
+
+/**
+ * Primary UI component for user interaction
+ */
+export const Button = ({ primary, backgroundColor, size, label, ...props }) => {
+ return (
+
+ {label}
+
+ );
+};
+
+Button.propTypes = {
+ /**
+ * Is this the principal call to action on the page?
+ */
+ primary: PropTypes.bool,
+ /**
+ * What background color to use
+ */
+ backgroundColor: PropTypes.string,
+ /**
+ * How large should the button be?
+ */
+ size: PropTypes.oneOf(["small", "medium", "large"]),
+ /**
+ * Button contents
+ */
+ label: PropTypes.string.isRequired,
+ /**
+ * Optional click handler
+ */
+ onPress: PropTypes.func,
+};
+
+Button.defaultProps = {
+ backgroundColor: null,
+ primary: false,
+ size: "medium",
+ onPress: undefined,
+};
diff --git a/with-storybook/stories/Button.stories.js b/with-storybook/stories/Button.stories.js
new file mode 100644
index 00000000..e085f9ed
--- /dev/null
+++ b/with-storybook/stories/Button.stories.js
@@ -0,0 +1,45 @@
+import { Button } from './Button';
+
+// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
+export default {
+ title: 'Example/Button',
+ component: Button,
+ parameters: {
+ // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
+ layout: 'centered',
+ },
+ // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/react/writing-docs/autodocs
+ tags: ['autodocs'],
+ // More on argTypes: https://storybook.js.org/docs/react/api/argtypes
+ argTypes: {
+ backgroundColor: { control: 'color' },
+ },
+};
+
+// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
+export const Primary = {
+ args: {
+ primary: true,
+ label: 'Button',
+ },
+};
+
+export const Secondary = {
+ args: {
+ label: 'Button',
+ },
+};
+
+export const Large = {
+ args: {
+ size: 'large',
+ label: 'Button',
+ },
+};
+
+export const Small = {
+ args: {
+ size: 'small',
+ label: 'Button',
+ },
+};
diff --git a/with-storybook/stories/Configure.mdx b/with-storybook/stories/Configure.mdx
new file mode 100644
index 00000000..a50fcea3
--- /dev/null
+++ b/with-storybook/stories/Configure.mdx
@@ -0,0 +1,364 @@
+import { Meta } from "@storybook/blocks";
+
+import Github from "./assets/github.svg";
+import Discord from "./assets/discord.svg";
+import Youtube from "./assets/youtube.svg";
+import Tutorials from "./assets/tutorials.svg";
+import Styling from "./assets/styling.png";
+import Context from "./assets/context.png";
+import Assets from "./assets/assets.png";
+import Docs from "./assets/docs.png";
+import Share from "./assets/share.png";
+import FigmaPlugin from "./assets/figma-plugin.png";
+import Testing from "./assets/testing.png";
+import Accessibility from "./assets/accessibility.png";
+import Theming from "./assets/theming.png";
+import AddonLibrary from "./assets/addon-library.png";
+
+export const RightArrow = () =>
+
+
+
+
+
+ # Configure your project
+
+ Because Storybook works separately from your app, you'll need to configure it for your specific stack and setup. Below, explore guides for configuring Storybook with popular frameworks and tools. If you get stuck, learn how you can ask for help from our community.
+
+
+
+
+
Add styling and CSS
+
Like with web applications, there are many ways to include CSS within Storybook. Learn more about setting up styling within Storybook.
To link static files (like fonts) to your projects and stories, use the
+ `staticDirs` configuration option to specify folders to load when
+ starting Storybook.
+ # Do more with Storybook
+
+ Now that you know the basics, let's explore other parts of Storybook that will improve your experience. This list is just to get you started. You can customise Storybook in many ways to fit your needs.
+
+
+
+
+
+
+
Autodocs
+
Auto-generate living,
+ interactive reference documentation from your components and stories.