+
{children}
);
@@ -18,5 +27,7 @@ const Grid = module.exports = ({
Grid.propTypes = {
fluid: React.PropTypes.bool,
+ className: React.PropTypes.string,
+ style: React.PropTypes.object,
children: React.PropTypes.node
-}
+};
diff --git a/ui/src/components/grid/style.css b/ui/src/components/grid/style.css
index d84c891d..7c9a26b1 100644
--- a/ui/src/components/grid/style.css
+++ b/ui/src/components/grid/style.css
@@ -21,20 +21,16 @@
padding-left: var(--outer-margin);
}
-@media sm-viewport {
- .container {
+.container {
+ @media sm-viewport {
width: var(--container-sm, 46rem);
}
-}
-@media md-viewport {
- .container {
+ @media md-viewport {
width: var(--container-md, 61rem);
}
-}
-@media lg-viewport {
- .container {
+ @media lg-viewport {
width: var(--container-lg, 71rem);
}
}
diff --git a/ui/src/components/row/index.js b/ui/src/components/row/index.js
new file mode 100644
index 00000000..0a11669a
--- /dev/null
+++ b/ui/src/components/row/index.js
@@ -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 (
+
+ {children}
+
+ );
+};
+
+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
+ }), {})
+};
diff --git a/ui/src/components/row/readme.md b/ui/src/components/row/readme.md
new file mode 100644
index 00000000..50c7ad08
--- /dev/null
+++ b/ui/src/components/row/readme.md
@@ -0,0 +1,22 @@
+# `
`
+
+## 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(
+
+
+
+
+
+
+);
+```
+
+## usage
diff --git a/ui/src/components/row/style.css b/ui/src/components/row/style.css
new file mode 100644
index 00000000..35e7cdbd
--- /dev/null
+++ b/ui/src/components/row/style.css
@@ -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;
+ }
+}
diff --git a/ui/webpack/base.js b/ui/webpack/base.js
index 2d3299ff..0586093f 100644
--- a/ui/webpack/base.js
+++ b/ui/webpack/base.js
@@ -13,6 +13,7 @@ const plugins = {
postcss: {
plugins: [
require('postcss-modules-values'),
+ require('postcss-mixins')(),
require('postcss-cssnext')()
]
},
diff --git a/ui/yarn.lock b/ui/yarn.lock
index 4b83c123..b8b55c2d 100644
--- a/ui/yarn.lock
+++ b/ui/yarn.lock
@@ -1272,6 +1272,10 @@ callsites@^0.2.0:
version "0.2.0"
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:
version "2.1.0"
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"
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:
version "5.6.0"
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"
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"
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"
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:
version "1.0.0-rc"
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-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:
version "1.0.1"
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"
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:
version "2.1.5"
resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-2.1.5.tgz#46fc0363f01bab6a36a9abb01c229fcc45363094"
@@ -5456,6 +5493,12 @@ style-loader@^0.13.1:
dependencies:
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:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"