From e22c04034310c012c8f7c848a2db99cfbb7d59a6 Mon Sep 17 00:00:00 2001 From: Jonathan Lietzau Date: Thu, 17 May 2018 22:39:03 -0500 Subject: [PATCH] Split out initial code --- .storybook/config.js | 7 --- config/setupTests.js | 5 ++ {.storybook => config/storybook}/addons.js | 0 config/storybook/config.js | 29 ++++++++++ package.json | 5 +- public/index.html | 49 ++++------------ src/App.css | 28 --------- src/App.js | 21 ------- src/App.test.js | 9 --- src/containers/layout/App.jsx | 14 +++++ src/index.css | 5 -- src/index.js | 7 +-- src/init/dev.js | 4 ++ src/init/index.jsx | 43 ++++++++++++++ src/init/router.jsx | 12 ++++ src/init/store.js | 13 +++++ src/init/styledcomponents.js | 67 ++++++++++++++++++++++ src/logo.svg | 7 --- src/stories/index.js | 19 ------ src/storyshots.test.js | 10 ++++ yarn.lock | 49 +--------------- 21 files changed, 216 insertions(+), 187 deletions(-) delete mode 100644 .storybook/config.js create mode 100644 config/setupTests.js rename {.storybook => config/storybook}/addons.js (100%) create mode 100644 config/storybook/config.js delete mode 100644 src/App.css delete mode 100644 src/App.js delete mode 100644 src/App.test.js create mode 100644 src/containers/layout/App.jsx delete mode 100644 src/index.css create mode 100644 src/init/dev.js create mode 100644 src/init/index.jsx create mode 100644 src/init/router.jsx create mode 100644 src/init/store.js create mode 100644 src/init/styledcomponents.js delete mode 100644 src/logo.svg delete mode 100644 src/stories/index.js create mode 100644 src/storyshots.test.js diff --git a/.storybook/config.js b/.storybook/config.js deleted file mode 100644 index 3543021..0000000 --- a/.storybook/config.js +++ /dev/null @@ -1,7 +0,0 @@ -import { configure } from '@storybook/react'; - -function loadStories() { - require('../src/stories'); -} - -configure(loadStories, module); diff --git a/config/setupTests.js b/config/setupTests.js new file mode 100644 index 0000000..054e7c2 --- /dev/null +++ b/config/setupTests.js @@ -0,0 +1,5 @@ +// setup file +import { configure } from 'enzyme'; +import Adapter from 'enzyme-adapter-react-16'; + +configure({ adapter: new Adapter() }); diff --git a/.storybook/addons.js b/config/storybook/addons.js similarity index 100% rename from .storybook/addons.js rename to config/storybook/addons.js diff --git a/config/storybook/config.js b/config/storybook/config.js new file mode 100644 index 0000000..2edb8fc --- /dev/null +++ b/config/storybook/config.js @@ -0,0 +1,29 @@ +import React from 'react'; +import { configure, addDecorator, setAddon } from '@storybook/react'; + +import { setOptions } from '@storybook/addon-options'; +import { withKnobs } from '@storybook/addon-knobs/react'; +import JSXAddon from 'storybook-addon-jsx'; +import styles from "@sambego/storybook-styles"; + +import Provider from './Provider'; +import { MemoryRouter } from 'react-router'; + +import configureStore from '../src/bootstrap/configureStore'; + +addDecorator(story => ); +addDecorator(story => {story()}) +addDecorator(styles({ + boxSizing: 'border-box', + fontFamily: "'Helvetica Neue','Helvetica','Arial',sans-serif", + fontSize: '16px', + margin: 0, +})) +setAddon(JSXAddon) + +const req = require.context('../src/components/', true, /story\.(jsx|js)$/); +function loadStories() { + req.keys().forEach(filename => req(filename)); +} + +configure(loadStories, module); diff --git a/package.json b/package.json index 24c5b44..98eb582 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "build": "node scripts/build.js", "test": "node scripts/test.js --env=jsdom", "lint": "eslint . --fix", - "storybook": "start-storybook -p 9009 -s public", + "storybook": "start-storybook -p 9009 -s public -c config/storybook", "build-storybook": "build-storybook -s public" }, "devDependencies": { @@ -89,7 +89,8 @@ "src/**/*.{js,jsx,mjs}" ], "setupFiles": [ - "/config/polyfills.js" + "/config/polyfills.js", + "/config/setupTests.js" ], "testMatch": [ "/src/**/__tests__/**/*.{js,jsx,mjs}", diff --git a/public/index.html b/public/index.html index ed0ebaf..51ae61f 100644 --- a/public/index.html +++ b/public/index.html @@ -1,40 +1,15 @@ - - - - - - - - - React App - - - -
- - + + + + + + + Loading... + + + +
+ diff --git a/src/App.css b/src/App.css deleted file mode 100644 index c5c6e8a..0000000 --- a/src/App.css +++ /dev/null @@ -1,28 +0,0 @@ -.App { - text-align: center; -} - -.App-logo { - animation: App-logo-spin infinite 20s linear; - height: 80px; -} - -.App-header { - background-color: #222; - height: 150px; - padding: 20px; - color: white; -} - -.App-title { - font-size: 1.5em; -} - -.App-intro { - font-size: large; -} - -@keyframes App-logo-spin { - from { transform: rotate(0deg); } - to { transform: rotate(360deg); } -} diff --git a/src/App.js b/src/App.js deleted file mode 100644 index 203067e..0000000 --- a/src/App.js +++ /dev/null @@ -1,21 +0,0 @@ -import React, { Component } from 'react'; -import logo from './logo.svg'; -import './App.css'; - -class App extends Component { - render() { - return ( -
-
- logo -

Welcome to React

-
-

- To get started, edit src/App.js and save to reload. -

-
- ); - } -} - -export default App; diff --git a/src/App.test.js b/src/App.test.js deleted file mode 100644 index a754b20..0000000 --- a/src/App.test.js +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import App from './App'; - -it('renders without crashing', () => { - const div = document.createElement('div'); - ReactDOM.render(, div); - ReactDOM.unmountComponentAtNode(div); -}); diff --git a/src/containers/layout/App.jsx b/src/containers/layout/App.jsx new file mode 100644 index 0000000..16cb192 --- /dev/null +++ b/src/containers/layout/App.jsx @@ -0,0 +1,14 @@ +import React, { Fragment } from 'react'; +import Router from '../../init/router'; + +const App = () => ( + +
+
+ +
+
+
+); + +export default App; diff --git a/src/index.css b/src/index.css deleted file mode 100644 index b4cc725..0000000 --- a/src/index.css +++ /dev/null @@ -1,5 +0,0 @@ -body { - margin: 0; - padding: 0; - font-family: sans-serif; -} diff --git a/src/index.js b/src/index.js index fae3e35..e249e5b 100644 --- a/src/index.js +++ b/src/index.js @@ -1,8 +1,5 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import './index.css'; -import App from './App'; +import initApp from './init'; import registerServiceWorker from './registerServiceWorker'; -ReactDOM.render(, document.getElementById('root')); +initApp(); registerServiceWorker(); diff --git a/src/init/dev.js b/src/init/dev.js new file mode 100644 index 0000000..9e28684 --- /dev/null +++ b/src/init/dev.js @@ -0,0 +1,4 @@ +// logging +import { createLogger } from 'redux-logger'; + +exports.initDev = (middleware) => middleware.push(createLogger()); diff --git a/src/init/index.jsx b/src/init/index.jsx new file mode 100644 index 0000000..0af068a --- /dev/null +++ b/src/init/index.jsx @@ -0,0 +1,43 @@ +import React from 'react'; +import { render } from 'react-snapshot'; + +// redux / state +import { Provider } from 'react-redux'; +import thunk from 'redux-thunk'; + +// routing +import createHistory from 'history/createBrowserHistory'; +import { BrowserRouter } from 'react-router-dom'; +import { routerMiddleware } from 'react-router-redux'; + +// app +import initStore from './store'; +import App from '../containers/layout/App'; +import styleInit from './styledComponents'; + +// api (todo make it an import) +const Api = {}; + +// middleware +const history = createHistory(); +const middleware = [routerMiddleware(history), thunk.withExtraArgument(Api)]; +if (process.env.NODE_ENV !== 'production') { + const initDev = require('./dev.js'); + initDev(middleware); +} + +const store = initStore(middleware); + +styleInit(); + +// todo consider using ConnectedRouter +export default function init() { + render( + + + + + , + document.getElementById('root'), + ); +} diff --git a/src/init/router.jsx b/src/init/router.jsx new file mode 100644 index 0000000..7ef010c --- /dev/null +++ b/src/init/router.jsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { Switch, Route } from 'react-router-dom'; + +const PlaceholderPage = (
Placeholder
); + +const Router = () => ( + + + +); + +export default Router; diff --git a/src/init/store.js b/src/init/store.js new file mode 100644 index 0000000..304f9ca --- /dev/null +++ b/src/init/store.js @@ -0,0 +1,13 @@ +import { createStore, combineReducers, applyMiddleware } from 'redux'; +import { routerReducer } from 'react-router-redux'; + +const combinedReducers = combineReducers({ + router: routerReducer, +}); + +const initState = {}; + +const configureStore = (middleware = []) => + createStore(combinedReducers, initState, applyMiddleware(...middleware)); + +export default configureStore; diff --git a/src/init/styledcomponents.js b/src/init/styledcomponents.js new file mode 100644 index 0000000..dde5761 --- /dev/null +++ b/src/init/styledcomponents.js @@ -0,0 +1,67 @@ +// these sizes are arbitrary and you can set them to whatever you wish +import { css, injectGlobal } from 'styled-components'; + +// global styles +export default () => injectGlobal(` + body { + box-sizing: border-box; + font-family: 'Helvetica Neue','Helvetica','Arial',sans-serif; + font-size: 16px; + margin: 0; + padding: 0 + } +`); + +// Helpers for accessability purposes +export const a11y = { + srOnly: () => css` + position: absolute; + width: 1px; + height: 1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + clip-path: inset(50%); + border: 0; + `, + srOnlyFocus: () => css` + &:active, &:focus { + position: static; + width: auto; + height: auto; + overflow: visible; + clip: auto; + white-space: normal; + clip-path: none; + } + `, + focus: () => css` + &:active, &:focus { + outline: 1px dashed #333; + outline-offset: 2px; + text-decoration: underline; + } + `, +}; + +// media queries +const sizes = { + mobile: 1000, +}; + +// iterate through the sizes and create a media template +export const media = Object.keys(sizes).reduce((accumulator, label) => { + // use em in breakpoints to work properly cross-browser and support users + // changing their browsers font-size: https://zellwk.com/blog/media-query-units/ + const emSize = sizes[label] / 16; + return { + ...accumulator, + [label]: (...args) => css` + @media (max-width: ${emSize}em) { + ${css(...args)} + } + `, + }; +}, {}); + diff --git a/src/logo.svg b/src/logo.svg deleted file mode 100644 index 6b60c10..0000000 --- a/src/logo.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/stories/index.js b/src/stories/index.js deleted file mode 100644 index aa04241..0000000 --- a/src/stories/index.js +++ /dev/null @@ -1,19 +0,0 @@ -import React from 'react'; - -import { storiesOf } from '@storybook/react'; -import { action } from '@storybook/addon-actions'; -import { linkTo } from '@storybook/addon-links'; - -import { Button, Welcome } from '@storybook/react/demo'; - -storiesOf('Welcome', module).add('to Storybook', () => ); - -storiesOf('Button', module) - .add('with text', () => ) - .add('with some emoji', () => ( - - )); diff --git a/src/storyshots.test.js b/src/storyshots.test.js new file mode 100644 index 0000000..9594ea3 --- /dev/null +++ b/src/storyshots.test.js @@ -0,0 +1,10 @@ +import initStoryshots from '@storybook/addon-storyshots'; +import { render } from 'enzyme'; + +const defaultRenderTest = ({ story, context }) => { + expect(render(story.render(context))).toMatchSnapshot(); +}; + +initStoryshots({ + test: defaultRenderTest, +}); diff --git a/yarn.lock b/yarn.lock index 73a6c89..884df9a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -683,7 +683,7 @@ babel-core@6.26.0: slash "^1.0.0" source-map "^0.5.6" -babel-core@^6.0.0, babel-core@^6.26.0, babel-core@^6.26.3: +babel-core@^6.0.0, babel-core@^6.26.0: version "6.26.3" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" dependencies: @@ -3944,7 +3944,7 @@ fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" -fsevents@^1.0.0, fsevents@^1.1.2, fsevents@^1.1.3: +fsevents@^1.0.0, fsevents@^1.1.2: version "1.2.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.3.tgz#08292982e7059f6674c93d8b829c1e8604979ac0" dependencies: @@ -7413,51 +7413,6 @@ react-router@^4.2.0: prop-types "^15.5.4" warning "^3.0.0" -react-scripts@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-1.1.4.tgz#d5c230e707918d6dd2d06f303b10f5222d017c88" - dependencies: - autoprefixer "7.1.6" - babel-core "6.26.0" - babel-eslint "7.2.3" - babel-jest "20.0.3" - babel-loader "7.1.2" - babel-preset-react-app "^3.1.1" - babel-runtime "6.26.0" - case-sensitive-paths-webpack-plugin "2.1.1" - chalk "1.1.3" - css-loader "0.28.7" - dotenv "4.0.0" - dotenv-expand "4.2.0" - eslint "4.10.0" - eslint-config-react-app "^2.1.0" - eslint-loader "1.9.0" - eslint-plugin-flowtype "2.39.1" - eslint-plugin-import "2.8.0" - eslint-plugin-jsx-a11y "5.1.1" - eslint-plugin-react "7.4.0" - extract-text-webpack-plugin "3.0.2" - file-loader "1.1.5" - fs-extra "3.0.1" - html-webpack-plugin "2.29.0" - jest "20.0.4" - object-assign "4.1.1" - postcss-flexbugs-fixes "3.2.0" - postcss-loader "2.0.8" - promise "8.0.1" - raf "3.4.0" - react-dev-utils "^5.0.1" - resolve "1.6.0" - style-loader "0.19.0" - sw-precache-webpack-plugin "0.11.4" - url-loader "0.6.2" - webpack "3.8.1" - webpack-dev-server "2.9.4" - webpack-manifest-plugin "1.3.2" - whatwg-fetch "2.0.3" - optionalDependencies: - fsevents "^1.1.3" - react-side-effect@^1.1.0: version "1.1.5" resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-1.1.5.tgz#f26059e50ed9c626d91d661b9f3c8bb38cd0ff2d"