ui grid system - grid, row and column

This commit is contained in:
Sérgio Ramos 2016-10-24 21:58:09 +01:00
parent 73ab7705af
commit 410f5a93e5
13 changed files with 547 additions and 17 deletions

View File

@ -22,7 +22,7 @@ const plugins = {
}), }),
'define-plugin': new webpack.DefinePlugin({ 'define-plugin': new webpack.DefinePlugin({
'process.env': { 'process.env': {
NODE_ENV: JSON.stringify(process.env['NODE_ENV'] || 'development'), NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development'),
APP_NAME: JSON.stringify(pkg.name), APP_NAME: JSON.stringify(pkg.name),
APP_VERSION: JSON.stringify(pkg.version) APP_VERSION: JSON.stringify(pkg.version)
} }

View File

@ -1,6 +1,6 @@
const React = require('react'); const React = require('react');
const ReactHotLoader = require('react-hot-loader'); const ReactHotLoader = require('react-hot-loader');
const Button = require('../src/components/grid/readme.md'); const Button = require('../src/components/column/readme.md');
const InnerHTML = require('dangerously-set-inner-html'); const InnerHTML = require('dangerously-set-inner-html');
const { const {

View File

@ -13,6 +13,7 @@
}, },
"dependencies": { "dependencies": {
"classnames": "^2.2.5", "classnames": "^2.2.5",
"lodash.flatten": "^4.4.0",
"react": "^15.3.2" "react": "^15.3.2"
}, },
"devDependencies": { "devDependencies": {
@ -42,6 +43,7 @@
"nyc": "^8.3.1", "nyc": "^8.3.1",
"postcss-cssnext": "^2.8.0", "postcss-cssnext": "^2.8.0",
"postcss-loader": "^1.0.0", "postcss-loader": "^1.0.0",
"postcss-mixins": "^5.4.0",
"postcss-modules-values": "^1.2.2", "postcss-modules-values": "^1.2.2",
"pre-commit": "^1.1.3", "pre-commit": "^1.1.3",
"raw-loader": "^0.5.1", "raw-loader": "^0.5.1",

View File

@ -0,0 +1,62 @@
/*
* based on
* https://github.com/roylee0704/react-flexbox-grid/blob/master/src/components/Col.js
*/
const flatten = require('lodash.flatten');
const classNames = require('classnames');
const React = require('react');
const styles = require('./style.css');
const breakpoints = [
'xs',
'sm',
'md',
'lg'
];
const getClasses = (props) => {
return flatten(breakpoints.map((size) => {
const number = props[size];
const offset = props[`${size}Offset`];
return [
number ? styles[`${size}-${number}`] : '',
offset ? styles[`${size}-offset-${offset}`] : ''
];
})).filter(Boolean);
};
const Column = module.exports = (props) => {
const {
className,
reverse,
children,
style
} = props;
const cn = classNames(
className,
styles.column,
reverse ? styles.reverse : '',
...getClasses(props)
);
return (
<div style={style} className={cn}>
{children}
</div>
);
};
Column.propTypes = {
reverse: React.PropTypes.bool,
className: React.PropTypes.string,
style: React.PropTypes.object,
children: React.PropTypes.node,
...breakpoints.reduce((all, bp) => ({
...all,
[`${bp}Offset`]: React.PropTypes.number,
[bp]: React.PropTypes.number
}), {})
};

View File

@ -0,0 +1,64 @@
# `<Column>`
## demo
```embed
const React = require('react');
const ReactDOM = require('react-dom/server');
const Grid = require('../grid');
const Row = require('../row');
const Column = require('./index');
const styles = {
grid: {
backgroundColor: '#FFEBEE'
},
row: {
backgroundColor: '#EF5350'
},
column: {
backgroundColor: '#B71C1C',
textAlign: 'center'
},
p: {
color: 'white'
}
};
nmodule.exports = ReactDOM.renderToString(
<Grid style={styles.grid}>
<Row style={styles.row} around>
<Column style={styles.column} xs={2}>
<p style={styles.p}>1</p>
</Column>
<Column style={styles.column} xs={2}>
<p style={styles.p}>2</p>
</Column>
<Column style={styles.column} xs={2}>
<p style={styles.p}>3</p>
</Column>
</Row>
</Grid>
);
```
## usage
```js
const React = require('react');
const Grid = require('ui/grid');
const Row = require('ui/row');
const Column = require('ui/index');
module.exports = () => {
return (
<Grid>
<Row around>
<Column xs={2}>1</Column>
<Column xs={2}>2</Column>
<Column xs={2}>3</Column>
</Row>
</Grid>
);
};
```

View File

@ -0,0 +1,152 @@
/*
* based on
* https://github.com/kristoferjoseph/flexboxgrid/blob/master/dist/flexboxgrid.css
*/
@value half-gutter-width from "../../constants/sizes.css";
@value sm-viewport, md-viewport, lg-viewport from "../../constants/breakpoints.css";
:root {
--half-gutter-width: half-gutter-width;
}
@define-mixin viewport $size {
&.$(size) {
flex-grow: 1;
flex-basis: 0;
max-width: 100%;
}
&.$(size)-1 {
flex-basis: 8.33333333%;
max-width: 8.33333333%;
}
&.$(size)-2 {
flex-basis: 16.66666667%;
max-width: 16.66666667%;
}
&.$(size)-3 {
flex-basis: 25%;
max-width: 25%;
}
&.$(size)-4 {
flex-basis: 33.33333333%;
max-width: 33.33333333%;
}
&.$(size)-5 {
flex-basis: 41.66666667%;
max-width: 41.66666667%;
}
&.$(size)-6 {
flex-basis: 50%;
max-width: 50%;
}
&.$(size)-7 {
flex-basis: 58.33333333%;
max-width: 58.33333333%;
}
&.$(size)-8 {
flex-basis: 66.66666667%;
max-width: 66.66666667%;
}
&.$(size)-9 {
flex-basis: 75%;
max-width: 75%;
}
&.$(size)-10 {
flex-basis: 83.33333333%;
max-width: 83.33333333%;
}
&.$(size)-11 {
flex-basis: 91.66666667%;
max-width: 91.66666667%;
}
&.$(size)-12 {
flex-basis: 100%;
max-width: 100%;
}
&.$(size)-offset-0 {
margin-left: 0;
}
&.$(size)-offset-1 {
margin-left: 8.33333333%;
}
&.$(size)-offset-2 {
margin-left: 16.66666667%;
}
&.$(size)-offset-3 {
margin-left: 25%;
}
&.$(size)-offset-4 {
margin-left: 33.33333333%;
}
&.$(size)-offset-5 {
margin-left: 41.66666667%;
}
&.$(size)-offset-6 {
margin-left: 50%;
}
&.$(size)-offset-7 {
margin-left: 58.33333333%;
}
&.$(size)-offset-8 {
margin-left: 66.66666667%;
}
&.$(size)-offset-9 {
margin-left: 75%;
}
&.$(size)-offset-10 {
margin-left: 83.33333333%;
}
&.$(size)-offset-11 {
margin-left: 91.66666667%;
}
}
.column {
box-sizing: border-box;
flex: 0 0 auto;
padding-right: var(--half-gutter-width, 0.5rem);
padding-left: var(--half-gutter-width, 0.5rem);
&.reverse {
flex-direction: column-reverse;
}
@mixin viewport xs;
@media sm-viewport {
@mixin viewport sm;
}
@media md-viewport {
@mixin viewport md;
}
@media lg-viewport {
@mixin viewport lg;
}
}

View File

@ -1,16 +1,25 @@
// based on https://github.com/roylee0704/react-flexbox-grid/blob/master/src/components/Grid.js /*
* based on
* https://github.com/roylee0704/react-flexbox-grid/blob/master/src/components/Grid.js
*/
const React = require('react'); const React = require('react');
const style = require('./style.css'); const classNames = require('classnames');
const styles = require('./style.css');
const Grid = module.exports = ({ const Grid = module.exports = ({
fluid = false, fluid = false,
children className,
children,
style
}) => { }) => {
const className = style[fluid ? 'container-fluid' : 'container']; const cn = classNames(
className,
styles[fluid ? 'container-fluid' : 'container']
);
return ( return (
<div className={className}> <div style={style} className={cn}>
{children} {children}
</div> </div>
); );
@ -18,5 +27,7 @@ const Grid = module.exports = ({
Grid.propTypes = { Grid.propTypes = {
fluid: React.PropTypes.bool, fluid: React.PropTypes.bool,
className: React.PropTypes.string,
style: React.PropTypes.object,
children: React.PropTypes.node children: React.PropTypes.node
} };

View File

@ -21,20 +21,16 @@
padding-left: var(--outer-margin); padding-left: var(--outer-margin);
} }
@media sm-viewport { .container {
.container { @media sm-viewport {
width: var(--container-sm, 46rem); width: var(--container-sm, 46rem);
} }
}
@media md-viewport { @media md-viewport {
.container {
width: var(--container-md, 61rem); width: var(--container-md, 61rem);
} }
}
@media lg-viewport { @media lg-viewport {
.container {
width: var(--container-lg, 71rem); width: var(--container-lg, 71rem);
} }
} }

View File

@ -0,0 +1,92 @@
/*
* based on
* https://github.com/roylee0704/react-flexbox-grid/blob/master/src/components/Row.js
*/
const flatten = require('lodash.flatten');
const classNames = require('classnames');
const React = require('react');
const styles = require('./style.css');
const breakpoints = [
'xs',
'sm',
'md',
'lg'
];
const modifiers = [
'start',
'center',
'end',
'top',
'middle',
'bottom',
'around',
'between',
'first',
'last'
];
const getClasses = (props) => {
return flatten(modifiers.map((name) => {
const value = props[name];
if (!value) {
return;
}
const bps = (() => {
if (value === true) {
return breakpoints
}
if (Array.isArray(value)) {
return value;
}
return [value];
})();
return flatten(bps.map(bp => styles[`${name}-${bp}`]));
})).filter(Boolean);
};
const Row = module.exports = (props) => {
const {
className,
reverse,
children,
style
} = props;
const cn = classNames(
className,
styles.row,
reverse ? styles.reverse : '',
...getClasses(props)
);
return (
<div style={style} className={cn}>
{children}
</div>
);
};
const ModificatorType = React.PropTypes.oneOfType([
React.PropTypes.bool,
React.PropTypes.arrayOf(React.PropTypes.oneOf(breakpoints)),
React.PropTypes.oneOf(breakpoints)
]);
Row.propTypes = {
reverse: React.PropTypes.bool,
className: React.PropTypes.string,
style: React.PropTypes.object,
children: React.PropTypes.node,
...modifiers.reduce((all, m) => ({
...all,
[m]: ModificatorType
}), {})
};

View File

@ -0,0 +1,22 @@
# `<Row>`
## demo
```embed
const React = require('react');
const ReactDOM = require('react-dom/server');
const Row = require('./index.js');
const Grid = require('../grid');
const Button = require('../button');
nmodule.exports = ReactDOM.renderToString(
<Grid>
<Row center='xs' start='sm'>
<Button>1</Button>
<Button>2</Button>
</Row>
</Grid>
);
```
## usage

View File

@ -0,0 +1,85 @@
/*
* based on
* https://github.com/kristoferjoseph/flexboxgrid/blob/master/dist/flexboxgrid.css
*/
@value gutter-compensation from "../../constants/sizes.css";
@value sm-viewport, md-viewport, lg-viewport from "../../constants/breakpoints.css";
:root {
--outer-margin: outer-margin;
--gutter-compensation: gutter-compensation;
}
@define-mixin viewport $size {
&.start-$(size) {
justify-content: flex-start;
text-align: start;
}
&.center-$(size) {
justify-content: center;
text-align: center;
}
&.end-$(size) {
justify-content: flex-end;
text-align: end;
}
&.top-$(size) {
align-items: flex-start;
}
&.middle-$(size) {
align-items: center;
}
&.bottom-$(size) {
align-items: flex-end;
}
&.around-$(size) {
justify-content: space-around;
}
&.between-$(size) {
justify-content: space-between;
}
&.first-$(size) {
order: -1;
}
&.last-$(size) {
order: 1;
}
}
.row {
box-sizing: border-box;
display: flex;
flex: 0 1 auto;
flex-direction: row;
flex-wrap: wrap;
margin-right: var(--gutter-compensation, -0.5rem);
margin-left: var(--gutter-compensation, -0.5rem);
&.reverse {
flex-direction: row-reverse;
}
@mixin viewport xs;
@media sm-viewport {
@mixin viewport sm;
}
@media md-viewport {
@mixin viewport md;
}
@media lg-viewport {
@mixin viewport lg;
}
}

View File

@ -13,6 +13,7 @@ const plugins = {
postcss: { postcss: {
plugins: [ plugins: [
require('postcss-modules-values'), require('postcss-modules-values'),
require('postcss-mixins')(),
require('postcss-cssnext')() require('postcss-cssnext')()
] ]
}, },

View File

@ -1272,6 +1272,10 @@ callsites@^0.2.0:
version "0.2.0" version "0.2.0"
resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca"
camelcase-css@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-1.0.1.tgz#157c4238265f5cf94a1dffde86446552cbf3f705"
camelcase-keys@^2.0.0: camelcase-keys@^2.0.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7"
@ -2671,6 +2675,16 @@ globby@^5.0.0:
pify "^2.0.0" pify "^2.0.0"
pinkie-promise "^2.0.0" pinkie-promise "^2.0.0"
globby@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/globby/-/globby-6.0.0.tgz#8f5710eda32296ac53f011a97dccc70e936685dc"
dependencies:
array-union "^1.0.1"
glob "^7.0.3"
object-assign "^4.0.1"
pify "^2.0.0"
pinkie-promise "^2.0.0"
got@^5.0.0: got@^5.0.0:
version "5.6.0" version "5.6.0"
resolved "https://registry.yarnpkg.com/got/-/got-5.6.0.tgz#bb1d7ee163b78082bbc8eb836f3f395004ea6fbf" resolved "https://registry.yarnpkg.com/got/-/got-5.6.0.tgz#bb1d7ee163b78082bbc8eb836f3f395004ea6fbf"
@ -3437,7 +3451,7 @@ lodash.filter@^4.4.0:
version "4.6.0" version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace" resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace"
lodash.flatten@^4.2.0, lodash.flatten@^4.4.0: lodash.flatten, lodash.flatten@^4.2.0, lodash.flatten@^4.4.0:
version "4.4.0" version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
@ -4363,6 +4377,13 @@ postcss-initial@^1.3.1:
lodash.template "^4.2.4" lodash.template "^4.2.4"
postcss "^5.0.19" postcss "^5.0.19"
postcss-js@^0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-0.1.3.tgz#8c0a5daa1c918b3073c4806a3c5b332c67250c03"
dependencies:
camelcase-css "^1.0.1"
postcss "^5.0.21"
postcss-load-config@^1.0.0-rc: postcss-load-config@^1.0.0-rc:
version "1.0.0-rc" version "1.0.0-rc"
resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-1.0.0-rc.tgz#8aed0d0fb94afe2c1ab0ba2ca69da3af5079e2cc" resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-1.0.0-rc.tgz#8aed0d0fb94afe2c1ab0ba2ca69da3af5079e2cc"
@ -4458,6 +4479,16 @@ postcss-minify-selectors@^2.0.4:
postcss "^5.0.14" postcss "^5.0.14"
postcss-selector-parser "^2.0.0" postcss-selector-parser "^2.0.0"
postcss-mixins:
version "5.4.0"
resolved "https://registry.yarnpkg.com/postcss-mixins/-/postcss-mixins-5.4.0.tgz#68b4705d1f2c505921f4a2f55bcf72a03b56fc01"
dependencies:
globby "^6.0.0"
postcss "^5.2.4"
postcss-js "^0.1.3"
postcss-simple-vars "^3.0.0"
sugarss "^0.2.0"
postcss-modules-extract-imports@^1.0.0: postcss-modules-extract-imports@^1.0.0:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.0.1.tgz#8fb3fef9a6dd0420d3f6d4353cf1ff73f2b2a341" resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.0.1.tgz#8fb3fef9a6dd0420d3f6d4353cf1ff73f2b2a341"
@ -4582,6 +4613,12 @@ postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.2.0:
indexes-of "^1.0.1" indexes-of "^1.0.1"
uniq "^1.0.1" uniq "^1.0.1"
postcss-simple-vars@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/postcss-simple-vars/-/postcss-simple-vars-3.0.0.tgz#1fa4ccb4b7151d9f0d52fb8ea19a15c1319599d6"
dependencies:
postcss "^5.0.21"
postcss-svgo@^2.1.1: postcss-svgo@^2.1.1:
version "2.1.5" version "2.1.5"
resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-2.1.5.tgz#46fc0363f01bab6a36a9abb01c229fcc45363094" resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-2.1.5.tgz#46fc0363f01bab6a36a9abb01c229fcc45363094"
@ -5456,6 +5493,12 @@ style-loader@^0.13.1:
dependencies: dependencies:
loader-utils "^0.2.7" loader-utils "^0.2.7"
sugarss@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/sugarss/-/sugarss-0.2.0.tgz#ac34237563327c6ff897b64742bf6aec190ad39e"
dependencies:
postcss "^5.2.4"
supports-color@^2.0.0: supports-color@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"