diff --git a/.eslintrc.js b/.eslintrc.js
index a2cb42d83..c60266d29 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -27,7 +27,8 @@ module.exports = {
'no-param-reassign': 0,
'new-cap': 0,
'import/no-unresolved': 'error',
- 'linebreak-style': 0
+ 'linebreak-style': 0,
+ 'import/no-named-as-default': 'off'
},
settings: {
'import/resolver': {
diff --git a/frontend/components/App/App.jsx b/frontend/components/App/App.jsx
new file mode 100644
index 000000000..0d58bf632
--- /dev/null
+++ b/frontend/components/App/App.jsx
@@ -0,0 +1,22 @@
+import React, { Component, PropTypes } from 'react';
+import { Style } from 'radium';
+import globalStyles from '../../styles/global';
+
+export class App extends Component {
+ static propTypes = {
+ children: PropTypes.element,
+ };
+
+ render () {
+ const { children } = this.props;
+
+ return (
+
+
+ {children}
+
+ );
+ }
+}
+
+export default App;
diff --git a/frontend/components/app/index.tests.jsx b/frontend/components/App/App.tests.jsx
similarity index 51%
rename from frontend/components/app/index.tests.jsx
rename to frontend/components/App/App.tests.jsx
index c8656e432..3e749d4ba 100644
--- a/frontend/components/app/index.tests.jsx
+++ b/frontend/components/App/App.tests.jsx
@@ -1,16 +1,16 @@
import React from 'react';
import expect from 'expect';
import { mount } from 'enzyme';
-import App from './index';
+import { App } from './App';
-describe('App', () => {
+describe('App - component', () => {
const component = mount();
it('renders', () => {
expect(component).toExist();
});
- it('renders the appropriate text', () => {
- expect(component.text()).toInclude('If you can read this, React is rendering correctly!');
+ it('renders the Style component', () => {
+ expect(component.find('Style').length).toEqual(1);
});
});
diff --git a/frontend/components/App/index.js b/frontend/components/App/index.js
new file mode 100644
index 000000000..e8ab2197c
--- /dev/null
+++ b/frontend/components/App/index.js
@@ -0,0 +1 @@
+export default from './App';
diff --git a/frontend/components/app/index.jsx b/frontend/components/app/index.jsx
deleted file mode 100644
index a469eeb40..000000000
--- a/frontend/components/app/index.jsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import React, { Component } from 'react';
-
-class App extends Component {
- render() {
- return (
-
-
Kolide
-
If you can read this, React is rendering correctly!
-
- );
- }
-}
-
-export default App;
diff --git a/frontend/components/app/styles.css b/frontend/components/app/styles.css
deleted file mode 100644
index e69de29bb..000000000
diff --git a/frontend/css/funcs.js b/frontend/css/funcs.js
deleted file mode 100644
index e33af3f9e..000000000
--- a/frontend/css/funcs.js
+++ /dev/null
@@ -1,16 +0,0 @@
-/**
- * Global CSS Functions.
- * @module css/funcs
- */
-module.exports = {
- /**
- * Returns a string
- * @param {...number} val - A positive or negative number.
- * @example
- * // returns "height: 5px;"
- height: px(5);
- */
- px: (val) => {
- return `${val}px`;
- },
-};
diff --git a/frontend/css/global.css b/frontend/css/global.css
deleted file mode 100644
index b0e79efcf..000000000
--- a/frontend/css/global.css
+++ /dev/null
@@ -1,12 +0,0 @@
-body {
- margin:px(40) auto;
- max-width:px(650);
- line-height:1.6;
- font-size:px(18);
- color:$mainColor;
- padding:0 px(10);
-}
-
-h1,h2,h3 {
- line-height:1.2;
-}
diff --git a/frontend/css/index.js b/frontend/css/index.js
deleted file mode 100644
index eddb81b30..000000000
--- a/frontend/css/index.js
+++ /dev/null
@@ -1,10 +0,0 @@
-require('normalize.css');
-require('./global.css');
-
-/**
- * Components.
- * Include all css files just if you need
- * to hot reload it. And make sure that you
- * use `webpack.optimize.DedupePlugin`
- */
-require('../components/app/styles.css');
diff --git a/frontend/css/vars.js b/frontend/css/vars.js
deleted file mode 100644
index 52be571cd..000000000
--- a/frontend/css/vars.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Global CSS Variables.
- * @module css/vars
- */
-export default {
- mainColor: '#333',
-};
diff --git a/frontend/index.jsx b/frontend/index.jsx
index 1037c2678..67f250e22 100644
--- a/frontend/index.jsx
+++ b/frontend/index.jsx
@@ -1,17 +1,9 @@
-import React from 'react';
-import { Provider } from 'react-redux';
-import { render } from 'react-dom';
+import ReactDOM from 'react-dom';
import routes from './router';
-import store from './redux/store';
if (typeof window !== 'undefined') {
const { document } = global;
const app = document.getElementById('app');
- const reactReduxApp = (
-
- {routes}
-
- );
- render(reactReduxApp, app);
+ ReactDOM.render(routes, app);
}
diff --git a/frontend/pages/HomePage/HomePage.jsx b/frontend/pages/HomePage/HomePage.jsx
new file mode 100644
index 000000000..1ebdbb156
--- /dev/null
+++ b/frontend/pages/HomePage/HomePage.jsx
@@ -0,0 +1,10 @@
+import React, { Component } from 'react';
+
+export class HomePage extends Component {
+ render () {
+ return Home page
;
+ }
+}
+
+export default HomePage;
+
diff --git a/frontend/pages/HomePage/index.js b/frontend/pages/HomePage/index.js
new file mode 100644
index 000000000..c19686525
--- /dev/null
+++ b/frontend/pages/HomePage/index.js
@@ -0,0 +1 @@
+export default from './HomePage';
diff --git a/frontend/router/index.jsx b/frontend/router/index.jsx
index 5c6a6226a..ff8ab0472 100644
--- a/frontend/router/index.jsx
+++ b/frontend/router/index.jsx
@@ -1,15 +1,22 @@
import React from 'react';
-import { Router, Route, browserHistory } from 'react-router';
+import { browserHistory, IndexRoute, Route, Router } from 'react-router';
+import { Provider } from 'react-redux';
+import radium from 'radium';
import { syncHistoryWithStore } from 'react-router-redux';
-import App from '../components/app';
+import App from '../components/App';
+import HomePage from '../pages/HomePage';
import store from '../redux/store';
const history = syncHistoryWithStore(browserHistory, store);
const routes = (
-
-
-
+
+
+
+
+
+
+
);
export default routes;
diff --git a/frontend/styles/color.js b/frontend/styles/color.js
new file mode 100644
index 000000000..fcc2e3361
--- /dev/null
+++ b/frontend/styles/color.js
@@ -0,0 +1,6 @@
+const grey = '#333333';
+
+export default {
+ grey,
+ primary: grey,
+};
diff --git a/frontend/styles/font.js b/frontend/styles/font.js
new file mode 100644
index 000000000..56759fc0f
--- /dev/null
+++ b/frontend/styles/font.js
@@ -0,0 +1,5 @@
+import { pxToRem } from './helpers';
+
+export default {
+ base: pxToRem(18),
+};
diff --git a/frontend/styles/global.js b/frontend/styles/global.js
new file mode 100644
index 000000000..7d3b10a29
--- /dev/null
+++ b/frontend/styles/global.js
@@ -0,0 +1,30 @@
+import normalize from 'radium-normalize';
+import { marginLonghand, paddingLonghand } from './helpers';
+import color from './color';
+import font from './font';
+import padding from './padding';
+
+const { auto, half, none, most } = padding;
+
+const defaultTopAndBottomMargin = marginLonghand(most, ['Bottom', 'Top']);
+const defaultLeftAndRightMargin = marginLonghand(auto, ['Left', 'Right']);
+const defaultTopAndBottomPadding = paddingLonghand(none, ['Bottom', 'Top']);
+const defaultLeftAndRightPadding = paddingLonghand(half, ['Left', 'Right']);
+const MAX_WIDTH = '650px';
+
+export default {
+ ...normalize,
+ body: {
+ color: color.primary,
+ ...defaultTopAndBottomMargin,
+ ...defaultLeftAndRightMargin,
+ ...defaultTopAndBottomPadding,
+ ...defaultLeftAndRightPadding,
+ fontSize: font.base,
+ lineHeight: 1.6,
+ maxWidth: MAX_WIDTH,
+ },
+ 'h1, h2, h3': {
+ lineHeight: 1.2,
+ },
+};
diff --git a/frontend/styles/helpers.js b/frontend/styles/helpers.js
new file mode 100644
index 000000000..df9243a66
--- /dev/null
+++ b/frontend/styles/helpers.js
@@ -0,0 +1,26 @@
+import { capitalize } from 'lodash';
+
+const BASE_FONT_SIZE = 16;
+const defaultSides = ['Bottom', 'Left', 'Right', 'Top'];
+
+const calculateSpace = (type, amount, sides = defaultSides) => {
+ const spaceObject = {};
+
+ sides.forEach((side) => {
+ spaceObject[`${type}${capitalize(side)}`] = amount;
+ });
+
+ return spaceObject;
+};
+
+export const marginLonghand = (amount, sides) => {
+ return calculateSpace('margin', amount, sides);
+};
+
+export const paddingLonghand = (amount, sides) => {
+ return calculateSpace('padding', amount, sides);
+};
+
+export const pxToRem = (targetSize) => {
+ return `${targetSize / BASE_FONT_SIZE}rem`;
+};
diff --git a/frontend/styles/helpers.tests.js b/frontend/styles/helpers.tests.js
new file mode 100644
index 000000000..b0cad885a
--- /dev/null
+++ b/frontend/styles/helpers.tests.js
@@ -0,0 +1,48 @@
+import expect from 'expect';
+import { marginLonghand, paddingLonghand, pxToRem } from './helpers';
+
+describe('Styles - helper', () => {
+ describe('#marginLonghand', () => {
+ it('returns all sides by default', () => {
+ expect(marginLonghand('10px')).toEqual({
+ marginBottom: '10px',
+ marginLeft: '10px',
+ marginRight: '10px',
+ marginTop: '10px',
+ });
+ });
+
+ it('allows specifying margin sides', () => {
+ expect(marginLonghand('5px', ['bottom', 'top'])).toEqual({
+ marginBottom: '5px',
+ marginTop: '5px',
+ });
+ });
+ });
+
+ describe('#paddingLonghand', () => {
+ it('returns all sides by default', () => {
+ expect(paddingLonghand('10px')).toEqual({
+ paddingBottom: '10px',
+ paddingLeft: '10px',
+ paddingRight: '10px',
+ paddingTop: '10px',
+ });
+ });
+
+ it('allows specifying margin sides', () => {
+ expect(paddingLonghand('auto', ['bottom', 'top'])).toEqual({
+ paddingBottom: 'auto',
+ paddingTop: 'auto',
+ });
+ });
+ });
+
+ describe('#pxToRem', () => {
+ it('calculates rem from the pixel input', () => {
+ expect(pxToRem(16)).toEqual('1rem');
+ expect(pxToRem(8)).toEqual('0.5rem');
+ });
+ });
+});
+
diff --git a/frontend/styles/padding.js b/frontend/styles/padding.js
new file mode 100644
index 000000000..fde1a59b4
--- /dev/null
+++ b/frontend/styles/padding.js
@@ -0,0 +1,9 @@
+import { pxToRem } from './helpers';
+
+export default {
+ auto: 'auto',
+ base: pxToRem(18),
+ half: pxToRem(9),
+ none: 0,
+ most: pxToRem(40),
+};
diff --git a/package.json b/package.json
index 9594c12a9..a49d8016c 100644
--- a/package.json
+++ b/package.json
@@ -36,6 +36,8 @@
"postcss-loader": "^0.8.0",
"precss": "^1.4.0",
"proxy-middleware": "^0.15.0",
+ "radium": "^0.18.1",
+ "radium-normalize": "^2.0.4",
"react": "^15.2.1",
"react-dom": "^15.2.1",
"react-redux": "^4.4.5",
diff --git a/webpack.config.js b/webpack.config.js
index 32c9bd281..503c0c1af 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -3,21 +3,11 @@ require('es6-promise').polyfill();
var path = require('path');
var webpack = require('webpack');
var autoprefixer = require('autoprefixer');
-var precss = require('precss');
-var functions = require('postcss-functions');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
-var postCssLoader = [
- 'css-loader?module',
- '&localIdentName=[name]__[local]___[hash:base64:5]',
- '&disableStructuralMinification',
- '!postcss-loader'
-];
-
var plugins = [
new webpack.NoErrorsPlugin(),
new webpack.optimize.DedupePlugin(),
- new ExtractTextPlugin('bundle.css'),
];
if (process.env.NODE_ENV === 'production') {
@@ -30,8 +20,6 @@ if (process.env.NODE_ENV === 'production') {
'process.env': {NODE_ENV: JSON.stringify('production')}
})
]);
-
- postCssLoader.splice(1, 1) // drop human readable names
};
var repo = __dirname
@@ -48,7 +36,6 @@ var config = {
plugins: plugins,
module: {
loaders: [
- {test: /\.css/, loader: ExtractTextPlugin.extract('style-loader', postCssLoader.join(''))},
{test: /\.(png|gif)$/, loader: 'url-loader?name=[name]@[hash].[ext]&limit=5000'},
{test: /\.svg$/, loader: 'url-loader?name=[name]@[hash].[ext]&limit=5000!svgo-loader?useConfig=svgo1'},
{test: /\.(pdf|ico|jpg|eot|otf|woff|ttf|mp4|webm)$/, loader: 'file-loader?name=[name]@[hash].[ext]'},
@@ -61,11 +48,10 @@ var config = {
]
},
resolve: {
- extensions: ['', '.js', '.jsx', '.css'],
+ extensions: ['', '.js', '.jsx'],
alias: {
'#app': path.join(repo, 'frontend'),
'#components': path.join(repo, 'frontend/components'),
- '#css': path.join(repo, 'frontend/css')
}
},
svgo1: {
@@ -85,15 +71,6 @@ var config = {
{removeTitle: true},
{removeDesc: true}
]
- },
- postcss: function() {
- return [autoprefixer, precss({
- variables: {
- variables: require(path.join(repo, 'frontend/css/vars'))
- }
- }), functions({
- functions: require(path.join(repo, 'frontend/css/funcs'))
- })]
}
};