diff --git a/storybook/addons.js b/.storybook/addons.js similarity index 100% rename from storybook/addons.js rename to .storybook/addons.js diff --git a/.storybook/config.js b/.storybook/config.js new file mode 100644 index 0000000..c0543c0 --- /dev/null +++ b/.storybook/config.js @@ -0,0 +1,56 @@ +import React from 'react'; +import { configure, addDecorator } from '@storybook/react'; +import { RootThemeProvider } from '../src/components/App/RootThemeProvider'; +import './styles.css'; + +const themeDecorator = story => ( + {story()} +); +addDecorator(themeDecorator); + +// This condition actually should detect if it's an Node environment +// https://stackoverflow.com/questions/38332094/how-can-i-mock-webpacks-require-context-in-jest/42191018#42191018 +if (typeof require.context === 'undefined') { + const fs = require('fs'); + const path = require('path'); + + require.context = ( + base = '.', + scanSubDirectories = false, + regularExpression = /\.js$/ + ) => { + const files = {}; + + function readDirectory(directory) { + fs.readdirSync(directory).forEach(file => { + const fullPath = path.resolve(directory, file); + + if (fs.statSync(fullPath).isDirectory()) { + if (scanSubDirectories) readDirectory(fullPath); + + return; + } + + if (!regularExpression.test(fullPath)) return; + + files[fullPath] = true; + }); + } + + readDirectory(path.resolve(__dirname, base)); + + function Module(file) { + return require(file); + } + + Module.keys = () => Object.keys(files); + + return Module; + }; +} + +const req = require.context('../src', true, /\.stories\.tsx$/); + +configure(() => { + req.keys().forEach(filename => req(filename)); +}, module); diff --git a/storybook/styles.css b/.storybook/styles.css similarity index 100% rename from storybook/styles.css rename to .storybook/styles.css diff --git a/package.json b/package.json index 5eb7812..8b0cb9e 100644 --- a/package.json +++ b/package.json @@ -26,10 +26,10 @@ "styled-components": "^3.3.3" }, "devDependencies": { - "@storybook/addon-actions": "^3.4.7", - "@storybook/addon-storyshots": "^3.4.7", - "@storybook/addons": "^3.4.7", - "@storybook/react": "^3.4.7", + "@storybook/addon-actions": "^4.1.2", + "@storybook/addon-storyshots": "^4.1.2", + "@storybook/addons": "^4.1.2", + "@storybook/react": "^4.1.2", "@types/enzyme": "^3.1.10", "@types/graphql": "^0.13.0", "@types/jest": "^23.1.0", @@ -38,8 +38,8 @@ "@types/react-redux": "^6.0.2", "@types/react-router-dom": "^4.2.7", "@types/react-side-effect": "^1.1.0", - "@types/storybook__addon-actions": "^3.0.3", - "@types/storybook__react": "^3.0.7", + "@types/storybook__addon-actions": "^3.4.1", + "@types/storybook__react": "^4.0.0", "apollo-server-express": "^2.3.1", "enzyme": "^3.3.0", "enzyme-adapter-react-16": "^1.1.1", @@ -62,7 +62,7 @@ "scripts": { "fmt": "prettier --write $npm_package_config_prettierFiles", "check-all": "yarn query-codegen && yarn lint && CI=true yarn test", - "storybook": "REACT_APP_MOCK_RESOLVER=true start-storybook -p 9001 -c storybook", + "storybook": "REACT_APP_MOCK_RESOLVER=true start-storybook -p 9001 -c ./.storybook", "start-mock": "REACT_APP_MOCK_RESOLVER=true yarn start", "start": "react-scripts start", "build": "yarn query-codegen && react-scripts build", diff --git a/src/storyshots.test.ts b/src/storyshots.test.ts index b5066bb..1dd1b17 100644 --- a/src/storyshots.test.ts +++ b/src/storyshots.test.ts @@ -1,4 +1,4 @@ import initStoryshots, { renderOnly } from '@storybook/addon-storyshots'; -const configPath = './storybook'; +const configPath = './.storybook'; initStoryshots({ suite: 'Smoke StoryShots', configPath, test: renderOnly }); diff --git a/storybook/config.js b/storybook/config.js deleted file mode 100644 index 8f4eb90..0000000 --- a/storybook/config.js +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react'; -import { configure, addDecorator } from '@storybook/react'; -import { RootThemeProvider } from '../src/components/App/RootThemeProvider'; -import './styles.css'; - -const themeDecorator = story => ( - {story()} -); -addDecorator(themeDecorator); - -const req = require.context('../../src', true, /\.stories\.tsx$/); - -configure(() => { - req.keys().forEach(filename => req(filename)); -}, module); diff --git a/storybook/env.js b/storybook/env.js deleted file mode 100644 index 8b39b6c..0000000 --- a/storybook/env.js +++ /dev/null @@ -1,90 +0,0 @@ -'use strict'; - -const fs = require('fs'); -const path = require('path'); -const paths = require('./paths'); - -// Make sure that including paths.js after env.js will read .env variables. -delete require.cache[require.resolve('./paths')]; - -const NODE_ENV = process.env.NODE_ENV; -if (!NODE_ENV) { - throw new Error( - 'The NODE_ENV environment variable is required but was not specified.' - ); -} - -// https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use -var dotenvFiles = [ - `${paths.dotenv}.${NODE_ENV}.local`, - `${paths.dotenv}.${NODE_ENV}`, - // Don't include `.env.local` for `test` environment - // since normally you expect tests to produce the same - // results for everyone - NODE_ENV !== 'test' && `${paths.dotenv}.local`, - paths.dotenv, -].filter(Boolean); - -// Load environment variables from .env* files. Suppress warnings using silent -// if this file is missing. dotenv will never modify any environment variables -// that have already been set. -// https://github.com/motdotla/dotenv -dotenvFiles.forEach(dotenvFile => { - if (fs.existsSync(dotenvFile)) { - require('dotenv').config({ - path: dotenvFile, - }); - } -}); - -// We support resolving modules according to `NODE_PATH`. -// This lets you use absolute paths in imports inside large monorepos: -// https://github.com/facebookincubator/create-react-app/issues/253. -// It works similar to `NODE_PATH` in Node itself: -// https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders -// Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored. -// Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims. -// https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421 -// We also resolve them to make sure all tools using them work consistently. -const appDirectory = fs.realpathSync(process.cwd()); -process.env.NODE_PATH = (process.env.NODE_PATH || '') - .split(path.delimiter) - .filter(folder => folder && !path.isAbsolute(folder)) - .map(folder => path.resolve(appDirectory, folder)) - .join(path.delimiter); - -// Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be -// injected into the application via DefinePlugin in Webpack configuration. -const REACT_APP = /^REACT_APP_/i; - -function getClientEnvironment(publicUrl) { - const raw = Object.keys(process.env) - .filter(key => REACT_APP.test(key)) - .reduce( - (env, key) => { - env[key] = process.env[key]; - return env; - }, - { - // Useful for determining whether we’re running in production mode. - // Most importantly, it switches React into the correct mode. - NODE_ENV: process.env.NODE_ENV || 'development', - // Useful for resolving the correct path to static assets in `public`. - // For example, . - // This should only be used as an escape hatch. Normally you would put - // images into the `src` and `import` them in code to get their paths. - PUBLIC_URL: publicUrl, - } - ); - // Stringify all values so we can feed into Webpack DefinePlugin - const stringified = { - 'process.env': Object.keys(raw).reduce((env, key) => { - env[key] = JSON.stringify(raw[key]); - return env; - }, {}), - }; - - return { raw, stringified }; -} - -module.exports = getClientEnvironment; diff --git a/storybook/paths.js b/storybook/paths.js deleted file mode 100644 index 1df7516..0000000 --- a/storybook/paths.js +++ /dev/null @@ -1,57 +0,0 @@ -'use strict'; - -const path = require('path'); -const fs = require('fs'); -const url = require('url'); - -// Make sure any symlinks in the project folder are resolved: -// https://github.com/facebookincubator/create-react-app/issues/637 -const appDirectory = fs.realpathSync(process.cwd()); -const resolveApp = relativePath => path.resolve(appDirectory, relativePath); - -const envPublicUrl = process.env.PUBLIC_URL; - -function ensureSlash(path, needsSlash) { - const hasSlash = path.endsWith('/'); - if (hasSlash && !needsSlash) { - return path.substr(path, path.length - 1); - } else if (!hasSlash && needsSlash) { - return `${path}/`; - } else { - return path; - } -} - -const getPublicUrl = appPackageJson => - envPublicUrl || require(appPackageJson).homepage; - -// We use `PUBLIC_URL` environment variable or "homepage" field to infer -// "public path" at which the app is served. -// Webpack needs to know it to put the right