Changes CSS styles to JS using Radium (#129)

This commit is contained in:
Mike Stone 2016-09-07 16:07:45 -04:00 committed by Mike Arpaia
parent 88e4be20df
commit 906bf79526
22 changed files with 181 additions and 103 deletions

View File

@ -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': {

View File

@ -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 (
<div>
<Style rules={globalStyles} />
{children}
</div>
);
}
}
export default App;

View File

@ -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(<App />);
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);
});
});

View File

@ -0,0 +1 @@
export default from './App';

View File

@ -1,14 +0,0 @@
import React, { Component } from 'react';
class App extends Component {
render() {
return (
<div className="App">
<h1>Kolide</h1>
<p>If you can read this, React is rendering correctly!</p>
</div>
);
}
}
export default App;

View File

@ -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`;
},
};

View File

@ -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;
}

View File

@ -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');

View File

@ -1,7 +0,0 @@
/**
* Global CSS Variables.
* @module css/vars
*/
export default {
mainColor: '#333',
};

View File

@ -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 = (
<Provider store={store}>
{routes}
</Provider>
);
render(reactReduxApp, app);
ReactDOM.render(routes, app);
}

View File

@ -0,0 +1,10 @@
import React, { Component } from 'react';
export class HomePage extends Component {
render () {
return <div>Home page</div>;
}
}
export default HomePage;

View File

@ -0,0 +1 @@
export default from './HomePage';

View File

@ -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 = (
<Router history={history}>
<Route path="/" component={App} />
</Router>
<Provider store={store}>
<Router history={history}>
<Route path="/" component={radium(App)}>
<IndexRoute component={radium(HomePage)} />
</Route>
</Router>
</Provider>
);
export default routes;

6
frontend/styles/color.js Normal file
View File

@ -0,0 +1,6 @@
const grey = '#333333';
export default {
grey,
primary: grey,
};

5
frontend/styles/font.js Normal file
View File

@ -0,0 +1,5 @@
import { pxToRem } from './helpers';
export default {
base: pxToRem(18),
};

30
frontend/styles/global.js Normal file
View File

@ -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,
},
};

View File

@ -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`;
};

View File

@ -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');
});
});
});

View File

@ -0,0 +1,9 @@
import { pxToRem } from './helpers';
export default {
auto: 'auto',
base: pxToRem(18),
half: pxToRem(9),
none: 0,
most: pxToRem(40),
};

View File

@ -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",

View File

@ -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'))
})]
}
};