Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .storybook/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = {
stories: ['../components/**/*.stories.@(js|jsx|ts|tsx)'],
addons: [
'@storybook/addon-ondevice-actions',
'@storybook/addon-ondevice-controls',
'@storybook/addon-ondevice-backgrounds',
'@storybook/addon-ondevice-notes',
'@storybook/addon-docs',
],
};
10 changes: 7 additions & 3 deletions app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,6 @@ function MySplashScreen({ opacity }: { opacity: Animated.Value }) {
/>
</Animated.View>
);
}

/**
* Stack navigation component
*/
Expand Down Expand Up @@ -199,7 +197,7 @@ function MainStack() {
/**
* Main application component
*/
export default function RootLayout() {
export function RootLayout() {
const { init: initializeNDK } = useNDK();
const [appIsReady, setAppIsReady] = useState(false);
const scaleRef = useRef(new Animated.Value(1));
Expand Down Expand Up @@ -280,3 +278,9 @@ export default function RootLayout() {
</SafeAreaProvider>
);
}


const AppEntry = process.env.EXPO_PUBLIC_STORYBOOK_ENABLED === "true" ? require("../storybook").default : RootLayout;

export default AppEntry;

30 changes: 30 additions & 0 deletions components/storybook/MyButton.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { Meta, StoryObj } from '@storybook/react';
import { View } from 'react-native';
import { MyButton } from './MyButton';

const noop = () => {};

const meta = {
title: 'MyButton',
component: MyButton,
args: {
text: 'Hello world',
},
decorators: [
(Story) => (
<View style={{ padding: 16 }}>
<Story />
</View>
),
],
} satisfies Meta<typeof MyButton>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Basic: Story = {
args: {
onPress: noop,
},
};
13 changes: 13 additions & 0 deletions components/storybook/MyButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';
import { Pressable, Text } from 'react-native';

export interface MyButtonProps {
text: string;
onPress?: () => void;
}

export const MyButton = ({ text, onPress }: MyButtonProps) => (
<Pressable onPress={onPress} style={{ padding: 12, borderRadius: 4, backgroundColor: '#3478f6' }}>
<Text style={{ color: '#fff', textAlign: 'center' }}>{text}</Text>
</Pressable>
);
6 changes: 5 additions & 1 deletion metro.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const { getDefaultConfig } = require('@expo/metro-config');
const { withMonicon } = require('@monicon/metro');
const { withNativeWind } = require('nativewind/metro');
const withStorybook = require('@storybook/react-native/metro/withStorybook');

const config = getDefaultConfig(__dirname);
config.resolver.unstable_conditionNames = ['browser', 'require', 'react-native'];
Expand Down Expand Up @@ -89,4 +90,7 @@ const configWithMonicon = withMonicon(config, {
// Then apply NativeWind
const finalConfig = withNativeWind(configWithMonicon, { input: './global.css' });

module.exports = finalConfig;
module.exports = withStorybook(finalConfig, {
enabled: process.env.EXPO_PUBLIC_STORYBOOK_ENABLED === 'true',
onDisabledRemoveStorybook: true,
});
18 changes: 16 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@
"build:android:apk": "eas build -p android --profile preview",
"submit:android": "eas submit -p android",
"pretty": "prettier --write \"./**/*.{js,jsx,mjs,cjs,ts,tsx,json}\"",
"lint": "expo lint"
"lint": "expo lint",
"storybook:web": "storybook dev -p 6006",
"build-storybook": "storybook build",
"storybook-generate": "sb-rn-get-stories",
"storybook": "cross-env EXPO_PUBLIC_STORYBOOK_ENABLED='true' expo start",
"storybook:ios": "cross-env EXPO_PUBLIC_STORYBOOK_ENABLED='true' expo start --ios",
"storybook:android": "cross-env EXPO_PUBLIC_STORYBOOK_ENABLED='true' expo start --android"
},
"jest": {
"preset": "jest-expo",
Expand Down Expand Up @@ -55,7 +61,7 @@
"@scure/bip39": "^1.2.2",
"@shopify/flash-list": "1.7.6",
"@shopify/react-native-skia": "^2.0.0-next.3",
"@storybook/react-native": "^9.0.14",
"@storybook/react-native": "^9",
"@tanstack/react-query": "^5.66.0",
"axios": "^1.10.0",
"bip39": "^3.1.0",
Expand Down Expand Up @@ -183,11 +189,19 @@
"@babel/preset-env": "^7.28.0",
"@gandlaf21/bc-ur": "^1.1.12",
"@react-native-community/cli": "latest",
"@storybook/addon-docs": "^9",
"@storybook/addon-ondevice-actions": "^9",
"@storybook/addon-ondevice-backgrounds": "^9",
"@storybook/addon-ondevice-controls": "^9",
"@storybook/addon-ondevice-notes": "^9",
"@storybook/react": "^9",
"@storybook/react-native-web-vite": "^9",
"@types/jest": "^30.0.0",
"@types/lodash": "^4.17.20",
"@types/mocha": "^10.0.10",
"@types/react": "^19.1.2",
"babel-jest": "^30.0.4",
"cross-env": "^7.0.3",
"eslint": "^9.0.0",
"eslint-config-expo": "~9.2.0",
"eslint-config-prettier": "^10.1.5",
Expand Down
6 changes: 6 additions & 0 deletions storybook/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { getStorybookUI } from '@storybook/react-native';
import './storybook.requires';

const StorybookUIRoot = getStorybookUI({});

export default StorybookUIRoot;
1 change: 1 addition & 0 deletions storybook/storybook.requires.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require('../components/storybook/MyButton.stories');
Loading