diff --git a/lib/cli/src/generators/REACT_NATIVE/index.ts b/lib/cli/src/generators/REACT_NATIVE/index.ts index df435c48e139..135b38585353 100644 --- a/lib/cli/src/generators/REACT_NATIVE/index.ts +++ b/lib/cli/src/generators/REACT_NATIVE/index.ts @@ -1,9 +1,9 @@ -import shell from 'shelljs'; import chalk from 'chalk'; -import { paddedLog, copyTemplate } from '../../helpers'; -import { NpmOptions } from '../../NpmOptions'; -import { baseGenerator, GeneratorOptions } from '../baseGenerator'; +import shell from 'shelljs'; +import { getBabelDependencies, paddedLog, copyTemplate } from '../../helpers'; import { JsPackageManager } from '../../js-package-manager'; +import { NpmOptions } from '../../NpmOptions'; +import { GeneratorOptions } from '../baseGenerator'; const generator = async ( packageManager: JsPackageManager, @@ -19,7 +19,7 @@ const generator = async ( const projectName = dirname.slice('ios/'.length, dirname.length - '.xcodeproj'.length - 1); if (projectName) { - shell.sed('-i', '%APP_NAME%', projectName, 'storybook/storybook.js'); + shell.sed('-i', '%APP_NAME%', projectName, 'storybook/index.js'); } else { paddedLog( chalk.red( @@ -35,14 +35,40 @@ const generator = async ( !packageJson.dependencies['react-dom'] && !packageJson.devDependencies['react-dom']; const reactVersion = packageJson.dependencies.react; - await baseGenerator(packageManager, npmOptions, options, 'react-native', { - extraPackages: [ - missingReactDom && reactVersion && `react-dom@${reactVersion}`, - installServer && '@storybook/react-native-server', - ].filter(Boolean), - addScripts: installServer, - addComponents: false, // We copy template-csf as it's wrapped in a storybook folder - }); + // should resolve to latest 5.3 version, this is required until react-native storybook supports v6 + const webAddonsV5 = [ + '@storybook/addon-links@^5.3', + '@storybook/addon-knobs@^5.3', + '@storybook/addon-actions@^5.3', + ]; + + const nativeAddons = ['@storybook/addon-ondevice-knobs', '@storybook/addon-ondevice-actions']; + + const packagesToResolve = [ + ...nativeAddons, + '@storybook/react-native', + installServer && '@storybook/react-native-server', + ].filter(Boolean); + + const resolvedPackages = await packageManager.getVersionedPackages(...packagesToResolve); + + const babelDependencies = await getBabelDependencies(packageManager, packageJson); + + const packages = [ + ...babelDependencies, + ...resolvedPackages, + ...webAddonsV5, + missingReactDom && reactVersion && `react-dom@${reactVersion}`, + ].filter(Boolean); + + packageManager.addDependencies({ ...npmOptions, packageJson }, packages); + + if (installServer) { + packageManager.addStorybookCommandInScripts({ + port: 7007, + }); + } + copyTemplate(__dirname, options.storyFormat); }; diff --git a/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/addons.js b/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/addons.js index 6aed412d04af..bc646c943eb4 100644 --- a/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/addons.js +++ b/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/addons.js @@ -1,2 +1,3 @@ import '@storybook/addon-actions/register'; import '@storybook/addon-links/register'; +import '@storybook/addon-knobs/register'; diff --git a/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/index.js b/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/index.js index 3f532f977435..f6a30232e53b 100644 --- a/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/index.js +++ b/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/index.js @@ -1,8 +1,14 @@ +// if you use expo remove this line import { AppRegistry } from 'react-native'; -import { getStorybookUI, configure } from '@storybook/react-native'; + +import { getStorybookUI, configure, addDecorator } from '@storybook/react-native'; +import { withKnobs } from '@storybook/addon-knobs'; import './rn-addons'; +// enables knobs for all stories +addDecorator(withKnobs); + // import stories configure(() => { require('./stories'); @@ -13,7 +19,7 @@ configure(() => { const StorybookUIRoot = getStorybookUI({}); // If you are using React Native vanilla and after installation you don't see your app name here, write it manually. -// If you use Expo you can safely remove this line. +// If you use Expo you should remove this line. AppRegistry.registerComponent('%APP_NAME%', () => StorybookUIRoot); export default StorybookUIRoot; diff --git a/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/rn-addons.js b/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/rn-addons.js index e69de29bb2d1..4d30f923173b 100644 --- a/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/rn-addons.js +++ b/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/rn-addons.js @@ -0,0 +1,2 @@ +import '@storybook/addon-ondevice-actions/register'; +import '@storybook/addon-ondevice-knobs/register'; diff --git a/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/stories/Button/Button.stories.js b/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/stories/Button/Button.stories.js new file mode 100644 index 000000000000..8f17adc8664f --- /dev/null +++ b/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/stories/Button/Button.stories.js @@ -0,0 +1,20 @@ +import { action } from '@storybook/addon-actions'; +import { text } from '@storybook/addon-knobs'; +import { storiesOf } from '@storybook/react-native'; +import React from 'react'; +import { Text } from 'react-native'; +import Button from '.'; +import CenterView from '../CenterView'; + +storiesOf('Button', module) + .addDecorator((getStory) => {getStory()}) + .add('with text', () => ( + + )) + .add('with some emoji', () => ( + + )); diff --git a/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/stories/Button/index.android.js b/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/stories/Button/index.android.js deleted file mode 100644 index 3c4c405180da..000000000000 --- a/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/stories/Button/index.android.js +++ /dev/null @@ -1,17 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { TouchableNativeFeedback } from 'react-native'; - -export default function Button({ onPress, children }) { - return {children}; -} - -Button.defaultProps = { - children: null, - onPress: () => {}, -}; - -Button.propTypes = { - children: PropTypes.node, - onPress: PropTypes.func, -}; diff --git a/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/stories/Button/index.ios.js b/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/stories/Button/index.js similarity index 100% rename from lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/stories/Button/index.ios.js rename to lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/stories/Button/index.js diff --git a/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/stories/Welcome/Welcome.stories.js b/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/stories/Welcome/Welcome.stories.js new file mode 100644 index 000000000000..98a964bc7146 --- /dev/null +++ b/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/stories/Welcome/Welcome.stories.js @@ -0,0 +1,6 @@ +import React from 'react'; +import { linkTo } from '@storybook/addon-links'; +import { storiesOf } from '@storybook/react-native'; +import Welcome from '.'; + +storiesOf('Welcome', module).add('to Storybook', () => ); diff --git a/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/stories/index.js b/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/stories/index.js index 5ec8c1887b36..5c9079ab2b00 100644 --- a/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/stories/index.js +++ b/lib/cli/src/generators/REACT_NATIVE/template-csf/storybook/stories/index.js @@ -1,25 +1,2 @@ -import React from 'react'; -import { Text } from 'react-native'; - -import { storiesOf } from '@storybook/react-native'; -import { action } from '@storybook/addon-actions'; -import { linkTo } from '@storybook/addon-links'; - -import Button from './Button'; -import CenterView from './CenterView'; -import Welcome from './Welcome'; - -storiesOf('Welcome', module).add('to Storybook', () => ); - -storiesOf('Button', module) - .addDecorator((getStory) => {getStory()}) - .add('with text', () => ( - - )) - .add('with some emoji', () => ( - - )); +import './Button/Button.stories'; +import './Welcome/Welcome.stories'; diff --git a/lib/cli/src/initiate.ts b/lib/cli/src/initiate.ts index fcde5281bc5f..d0cdf589e182 100644 --- a/lib/cli/src/initiate.ts +++ b/lib/cli/src/initiate.ts @@ -78,8 +78,7 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr logger.log(); }; - const REACT_NATIVE_DISCUSSION = - 'https://github.com/storybookjs/react-native/blob/master/app/react-native/docs/manual-setup.md'; + const REACT_NATIVE_REPO = 'https://github.com/storybookjs/react-native'; const runGenerator: () => Promise = () => { switch (projectType) { @@ -130,9 +129,9 @@ const installStorybook = (projectType: ProjectType, options: CommandOptions): Pr .then(() => { logger.log(chalk.red('NOTE: installation is not 100% automated.')); logger.log(`To quickly run Storybook, replace contents of your app entry with:\n`); - codeLog(["export default from './storybook';"]); - logger.log('\n For more in depth setup instructions, see:\n'); - logger.log(chalk.cyan(REACT_NATIVE_DISCUSSION)); + codeLog(["export {default} from './storybook';"]); + logger.log('\n For more in information, see the github readme:\n'); + logger.log(chalk.cyan(REACT_NATIVE_REPO)); logger.log(); }); }