mirror of
https://github.com/yldio/copilot.git
synced 2024-11-28 06:00:06 +02:00
wip rm css
This commit is contained in:
parent
21ccfd80e3
commit
557cd5a291
1
.gitignore
vendored
1
.gitignore
vendored
@ -151,3 +151,4 @@ $RECYCLE.BIN/
|
||||
|
||||
/cloudapi-graphql/credentials.json
|
||||
tap-xunit
|
||||
/dist
|
||||
|
@ -77,7 +77,7 @@
|
||||
"jsx-a11y/aria-proptypes": 2,
|
||||
"jsx-a11y/aria-role": 2,
|
||||
"jsx-a11y/aria-unsupported-elements": 2,
|
||||
"jsx-a11y/click-events-have-key-events": 2,
|
||||
"jsx-a11y/click-events-have-key-events": 1,
|
||||
"jsx-a11y/mouse-events-have-key-events": 2,
|
||||
"jsx-a11y/heading-has-content": 2,
|
||||
"jsx-a11y/html-has-lang": 2,
|
||||
@ -88,7 +88,7 @@
|
||||
"jsx-a11y/no-access-key": 2,
|
||||
"jsx-a11y/no-marquee": 2,
|
||||
"jsx-a11y/no-onchange": 2,
|
||||
"jsx-a11y/no-static-element-interactions": 2,
|
||||
"jsx-a11y/no-static-element-interactions": 1,
|
||||
"jsx-a11y/onclick-has-focus": 2,
|
||||
"jsx-a11y/onclick-has-role": 2,
|
||||
"jsx-a11y/role-has-required-aria-props": 2,
|
||||
@ -100,9 +100,7 @@
|
||||
"object-curly-newline": [2, {
|
||||
"minProperties": 1
|
||||
}],
|
||||
"sort-vars": [2, {
|
||||
"ignoreCase": true
|
||||
}],
|
||||
"sort-vars": 2,
|
||||
"prefer-const": 2,
|
||||
"no-mixed-spaces-and-tabs": 2,
|
||||
"new-cap": 2,
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "joyent-dashboard-frontend",
|
||||
"name": "joyent-portal-frontend",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"license": "private",
|
||||
|
23
package.json
23
package.json
@ -1,23 +1,22 @@
|
||||
{
|
||||
"name": "joyent-dashboard",
|
||||
"name": "joyent-portal",
|
||||
"version": "1.0.0",
|
||||
"description": "## Project Management",
|
||||
"private": true,
|
||||
"license": "MPL2",
|
||||
"main": "index.js",
|
||||
"homepage": "https://github.com/yldio/joyent-portal#readme",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/yldio/joyent-portal.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/yldio/joyent-portal/issues"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "make test",
|
||||
"precommit": "make -j4 lint",
|
||||
"prepush": "make test"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/yldio/joyent-dashboard.git"
|
||||
},
|
||||
"author": "",
|
||||
"license": "MPL2",
|
||||
"bugs": {
|
||||
"url": "https://github.com/yldio/joyent-dashboard/issues"
|
||||
},
|
||||
"homepage": "https://github.com/yldio/joyent-dashboard#readme",
|
||||
"dependencies": {
|
||||
"husky": "^0.11.9"
|
||||
},
|
||||
|
@ -1,11 +1,9 @@
|
||||
{
|
||||
"sourceMaps": "both",
|
||||
"presets": [
|
||||
"react",
|
||||
"es2015"
|
||||
"react"
|
||||
],
|
||||
"plugins": [
|
||||
"react-hot-loader/babel",
|
||||
"add-module-exports",
|
||||
"transform-exponentiation-operator",
|
||||
"syntax-async-functions",
|
||||
|
@ -1,6 +1,9 @@
|
||||
src/components/base/*.css
|
||||
node_modules
|
||||
webpack/embed-markdown-loader/node_modules
|
||||
coverage
|
||||
.nyc_output
|
||||
static/
|
||||
!static/index.html
|
||||
docs/static
|
||||
!docs/static/index.html
|
||||
docs/node_modules
|
||||
docs/webpack/embed-markdown-loader
|
||||
dist
|
||||
|
@ -1,6 +1,7 @@
|
||||
/node_modules
|
||||
node_modules
|
||||
coverage
|
||||
.nyc_output
|
||||
docs/static
|
||||
static
|
||||
webpack/embed-markdown-loader
|
||||
docs/node_modules
|
||||
docs/webpack/embed-markdown-loader
|
||||
dist
|
@ -100,9 +100,7 @@
|
||||
"object-curly-newline": [2, {
|
||||
"minProperties": 1
|
||||
}],
|
||||
"sort-vars": [2, {
|
||||
"ignoreCase": true
|
||||
}],
|
||||
"sort-vars": 2,
|
||||
"prefer-const": 2,
|
||||
"no-mixed-spaces-and-tabs": 2,
|
||||
"new-cap": 2,
|
||||
|
@ -1,8 +1,8 @@
|
||||
/src/components/base/*.css
|
||||
/node_modules
|
||||
src/components/base/*.css
|
||||
node_modules
|
||||
coverage
|
||||
.nyc_output
|
||||
docs/static
|
||||
static
|
||||
webpack/embed-markdown-loader
|
||||
|
||||
docs/node_modules
|
||||
docs/webpack/embed-markdown-loader
|
||||
dist
|
||||
|
@ -1,5 +1,9 @@
|
||||
{
|
||||
"syntax": "scss",
|
||||
"extends": "stylelint-config-standard",
|
||||
"processors": [
|
||||
"stylelint-processor-styled-components"
|
||||
],
|
||||
"rules": {
|
||||
"color-hex-case": "upper",
|
||||
"color-hex-length": "long",
|
||||
|
10
ui/Makefile
10
ui/Makefile
@ -8,7 +8,7 @@ SERVE := $(bindir)/http-server
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
BABEL_DISABLE_CACHE=1 NODE_ENV=test CONFIG=$(shell pwd)/webpack/index.js $(NYC) $(AVA) test/*.js $(TEST_ARGS)
|
||||
BABEL_DISABLE_CACHE=1 NODE_ENV=test $(NYC) $(AVA) test/*.js $(TEST_ARGS)
|
||||
|
||||
XUNIT_DIR := ${CIRCLE_TEST_REPORTS}/tap-xunit
|
||||
XUNIT := $(bindir)/tap-xunit
|
||||
@ -16,12 +16,16 @@ XUNIT_OUTPUT := >> ${CIRCLE_TEST_REPORTS}/tap-xunit/xunit-$(NAME)
|
||||
.PHONY: test-ci
|
||||
test-ci:
|
||||
mkdir -p $(XUNIT_DIR)
|
||||
BABEL_DISABLE_CACHE=1 NODE_ENV=test CONFIG=$(shell pwd)/webpack/index.js $(NYC) $(AVA) test/*.js -t | $(XUNIT) $(XUNIT_OUTPUT).xml
|
||||
BABEL_DISABLE_CACHE=1 NODE_ENV=test $(NYC) $(AVA) test/*.js -t | $(XUNIT) $(XUNIT_OUTPUT).xml
|
||||
|
||||
.PHONY: install-embed-markdown-loader
|
||||
install-embed-markdown-loader:
|
||||
cd webpack/embed-markdown-loader && yarn install --prefer-offline
|
||||
|
||||
.PHONY: install-docs
|
||||
install-docs:
|
||||
cd docs && yarn install --prefer-offline
|
||||
|
||||
.PHONY: install
|
||||
install: install-embed-markdown-loader
|
||||
yarn install --prefer-offline
|
||||
@ -54,7 +58,7 @@ clean:
|
||||
.PHONY: lint
|
||||
lint:
|
||||
$(bindir)/eslint .
|
||||
./scripts/stylelint
|
||||
$(bindir)/stylelint './src/**/*.js'
|
||||
|
||||
.PHONY: lint-ci
|
||||
lint-ci:
|
||||
|
9
ui/docs/.babelrc
Normal file
9
ui/docs/.babelrc
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "../.babelrc",
|
||||
"presets": [
|
||||
"es2015"
|
||||
],
|
||||
"plugins": [
|
||||
"react-hot-loader/babel"
|
||||
]
|
||||
}
|
30
ui/docs/package.json
Normal file
30
ui/docs/package.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "joyent-portal-ui-docs",
|
||||
"description": "Joyent UI Framework Documentation",
|
||||
"version": "1.0.0",
|
||||
"license": "private",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "webpack-dev-server --config webpack/index.js",
|
||||
"build": "NODE_ENV=production webpack --config webpack/index.js",
|
||||
"clean-static": "git check-ignore static/** | xargs rm"
|
||||
},
|
||||
"dependencies": {
|
||||
"dangerously-set-inner-html": "2.0.0",
|
||||
"react": "^15.4.1",
|
||||
"react-a11y": "^0.3.3",
|
||||
"react-dom": "^15.4.1",
|
||||
"react-hot-loader": "^3.0.0-beta.6",
|
||||
"react-router": "^4.0.0-alpha.4",
|
||||
"styled-components": "^1.1.2",
|
||||
"title-case": "^2.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-loader": "^6.2.8",
|
||||
"babel-preset-es2015": "^6.18.0",
|
||||
"json-loader": "^0.5.4",
|
||||
"raw-loader": "^0.5.1",
|
||||
"webpack": "^2.1.0-beta.27",
|
||||
"webpack-dev-server": "^1.16.2"
|
||||
}
|
||||
}
|
@ -7,19 +7,32 @@ const ReactRouter = require('react-router');
|
||||
const Navigation = require('./navigation.js');
|
||||
const Home = require('../home');
|
||||
const Item = require('../item/');
|
||||
// const Item = require('../../../src/components/range-slider');
|
||||
|
||||
const {
|
||||
Base,
|
||||
Container,
|
||||
Row,
|
||||
Column
|
||||
} = require('../../../src');
|
||||
} = require('@ui');
|
||||
|
||||
const {
|
||||
Match
|
||||
} = ReactRouter;
|
||||
|
||||
const styles = {
|
||||
base: {
|
||||
backgroundColor: '#FFEBEE'
|
||||
},
|
||||
row: {
|
||||
backgroundColor: '#EF5350'
|
||||
},
|
||||
column: {
|
||||
backgroundColor: '#B71C1C',
|
||||
textAlign: 'center',
|
||||
color: 'white'
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = () => {
|
||||
return (
|
||||
<Base>
|
||||
@ -33,19 +46,16 @@ module.exports = () => {
|
||||
<Navigation />
|
||||
</Column>
|
||||
<Column
|
||||
style={styles.base}
|
||||
md={10}
|
||||
sm={9}
|
||||
xs={12}
|
||||
>
|
||||
<Match
|
||||
component={Home}
|
||||
exactly
|
||||
pattern='/'
|
||||
/>
|
||||
<Match
|
||||
component={Item}
|
||||
pattern='/:parent?/:name'
|
||||
/>
|
||||
<Row style={styles.row} around>
|
||||
<Column style={styles.column} xs={1} sm={2} md={3} lg={4}>1</Column>
|
||||
<Column style={styles.column} xs={1} sm={2} md={3} lg={4}>2</Column>
|
||||
<Column style={styles.column} xs={1} sm={2} md={3} lg={4}>3</Column>
|
||||
</Row>
|
||||
</Column>
|
||||
</Row>
|
||||
</Container>
|
@ -2,7 +2,7 @@ const paramCase = require('param-case');
|
||||
const React = require('react');
|
||||
const ReactRouter = require('react-router');
|
||||
|
||||
const Docs = require('../../../src/docs');
|
||||
const Docs = require('@root/mds');
|
||||
|
||||
const {
|
||||
Link
|
@ -3,7 +3,7 @@ const InnerHTML = require('dangerously-set-inner-html');
|
||||
const React = require('react');
|
||||
const titleCase = require('title-case');
|
||||
|
||||
const Docs = require('../../../src/docs');
|
||||
const Docs = require('@root/mds');
|
||||
|
||||
const Item = ({
|
||||
params
|
31
ui/docs/src/mds.js
Normal file
31
ui/docs/src/mds.js
Normal file
@ -0,0 +1,31 @@
|
||||
module.exports = {
|
||||
'Getting Started': require('@ui/getting-started.md'),
|
||||
Guidelines: {
|
||||
Overview: require('@ui/guidelines/overview.md'),
|
||||
Layout: require('@ui/guidelines/layout.md')
|
||||
},
|
||||
Components: {
|
||||
// Avatar: require('@ui/components/avatar/readme.md'),
|
||||
// Base: require('@ui/components/base/readme.md'),
|
||||
// Container: require('@ui/components/container/readme.md'),
|
||||
// Row: require('@ui/components/row/readme.md'),
|
||||
// Input: require('@ui/components/input/readme.md'),
|
||||
// Icon: require('@ui/components/icon/readme.md'),
|
||||
// Radio: require('@ui/components/radio/readme.md'),
|
||||
// 'Radio Group': require('@ui/components/radio-group/readme.md'),
|
||||
// Select: require('@ui/components/select/readme.md'),
|
||||
// Column: require('@ui/components/column/readme.md'),
|
||||
// Button: require('@ui/components/button/readme.md'),
|
||||
// 'Button Icon': require('@ui/components/button-icon/readme.md'),
|
||||
// 'Range Slider': require('@ui/components/range-slider/readme.md'),
|
||||
// Toggle: require('@ui/components/toggle/readme.md'),
|
||||
// Notificaton: require('@ui/components/notification/readme.md'),
|
||||
// Checkbox: require('@ui/components/checkbox/readme.md'),
|
||||
// Tab: require('@ui/components/tabs/tab/readme.md'),
|
||||
// Tabs: require('@ui/components/tabs/readme.md'),
|
||||
// Widget: require('@ui/components/widget/readme.md'),
|
||||
// Pagination: require('@ui/components/pagination/readme.md'),
|
||||
// Modal: require('@ui/components/modal/readme.md')
|
||||
},
|
||||
FAQ: require('@ui/faq.md')
|
||||
};
|
11
ui/docs/static/index.html
vendored
Normal file
11
ui/docs/static/index.html
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
<!doctype html>
|
||||
<html lang='en-US'>
|
||||
<head>
|
||||
<title>Joyent UI Framework</title>
|
||||
<link href="theme.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<div id='root'></div>
|
||||
<script src='main.js'></script>
|
||||
</body>
|
||||
</html>
|
69
ui/docs/webpack/base.js
Normal file
69
ui/docs/webpack/base.js
Normal file
@ -0,0 +1,69 @@
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
const plugins = require('./plugins');
|
||||
|
||||
const CONTEXT = path.join(__dirname, '../../');
|
||||
const STATIC = path.join(__dirname, '../static');
|
||||
const DOCS = path.join(CONTEXT, 'docs');
|
||||
const NODE_MODULES = path.join(DOCS, 'node_modules');
|
||||
const SRC = path.join(CONTEXT, 'src');
|
||||
|
||||
const MODULES = [
|
||||
path.join(DOCS, 'node_modules'),
|
||||
path.join(CONTEXT, 'node_modules')
|
||||
];
|
||||
|
||||
const INCLUDE = [
|
||||
DOCS,
|
||||
SRC
|
||||
];
|
||||
|
||||
module.exports = {
|
||||
context: CONTEXT,
|
||||
entry: './docs/src/index.js',
|
||||
resolveLoader: {
|
||||
alias: {
|
||||
'embed-markdown-loader': path.join(__dirname, './embed-markdown-loader'),
|
||||
'babel-loader': path.join(NODE_MODULES, 'babel-loader'),
|
||||
'json-loader': path.join(NODE_MODULES, 'json-loader'),
|
||||
'raw-loader': path.join(NODE_MODULES, 'raw-loader')
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
modules: MODULES,
|
||||
alias: {
|
||||
'@root': path.join(DOCS, 'src'),
|
||||
'@ui': SRC
|
||||
}
|
||||
},
|
||||
output: {
|
||||
path: STATIC,
|
||||
publicPath: '/',
|
||||
filename: '[name].js'
|
||||
},
|
||||
plugins: [
|
||||
plugins['named-modules'],
|
||||
plugins['no-errors'],
|
||||
plugins['loader-options'],
|
||||
plugins['define']
|
||||
],
|
||||
module: {
|
||||
rules: [{
|
||||
test: /js?$/,
|
||||
exclude: [/node_modules/g],
|
||||
include: INCLUDE,
|
||||
loader: 'babel-loader'
|
||||
}, {
|
||||
test: /\.json?$/,
|
||||
exclude: [/node_modules/g],
|
||||
include: INCLUDE,
|
||||
loader: 'json-loader'
|
||||
}, {
|
||||
test: /\.md?$/,
|
||||
exclude: [/node_modules/g],
|
||||
include: INCLUDE,
|
||||
loader: 'raw-loader!embed-markdown-loader'
|
||||
}]
|
||||
}
|
||||
};
|
30
ui/docs/webpack/development.js
Normal file
30
ui/docs/webpack/development.js
Normal file
@ -0,0 +1,30 @@
|
||||
const base = require('./base');
|
||||
const plugins = require('./plugins');
|
||||
const path = require('path');
|
||||
|
||||
const STATIC = path.join(__dirname, '../static');
|
||||
|
||||
const devServer = {
|
||||
contentBase: [
|
||||
STATIC
|
||||
],
|
||||
hot: true,
|
||||
compress: true,
|
||||
lazy: false,
|
||||
historyApiFallback: {
|
||||
index: './index.html'
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = Object.assign(base, {
|
||||
entry: [
|
||||
'react-hot-loader/patch',
|
||||
'webpack-dev-server/client?http://localhost:8080',
|
||||
'webpack/hot/only-dev-server',
|
||||
'./docs/src/index.js'
|
||||
],
|
||||
plugins: base.plugins.concat([
|
||||
plugins['hot-module-replacement']
|
||||
]),
|
||||
devServer
|
||||
});
|
@ -1,10 +1,6 @@
|
||||
const WebpackShellPlugin = require('webpack-shell-plugin');
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin');
|
||||
const webpack = require('webpack');
|
||||
const path = require('path');
|
||||
|
||||
const cssFunctions = require('../src/shared/functions');
|
||||
const mixins = path.join(__dirname, '../src/shared/mixins.css');
|
||||
const pkg = require('../package.json');
|
||||
|
||||
module.exports = {
|
||||
@ -13,27 +9,8 @@ module.exports = {
|
||||
'hot-module-replacement': new webpack.HotModuleReplacementPlugin(),
|
||||
'named-modules': new webpack.NamedModulesPlugin(),
|
||||
'no-errors': new webpack.NoErrorsPlugin(),
|
||||
'extract-text': new ExtractTextPlugin({
|
||||
filename: '[name].css',
|
||||
allChunks: true
|
||||
}),
|
||||
'loader-options': new webpack.LoaderOptionsPlugin({
|
||||
options: {
|
||||
postcss: {
|
||||
plugins: [
|
||||
require('postcss-import')(),
|
||||
require('postcss-constants')({}),
|
||||
require('postcss-at-rules-variables')(),
|
||||
require('postcss-functions')({
|
||||
functions: cssFunctions
|
||||
}),
|
||||
require('postcss-mixins')({
|
||||
mixinsFiles: mixins
|
||||
}),
|
||||
require('postcss-for'),
|
||||
require('postcss-cssnext')()
|
||||
]
|
||||
},
|
||||
'embed-markdown-loader': {
|
||||
mode: 'plain'
|
||||
}
|
||||
@ -53,10 +30,5 @@ module.exports = {
|
||||
comments: false,
|
||||
indent_level: 2
|
||||
}
|
||||
}),
|
||||
'shell': new WebpackShellPlugin({
|
||||
onBuildEnd: [
|
||||
'npm run build-docs-static'
|
||||
]
|
||||
})
|
||||
};
|
||||
};
|
20
ui/docs/webpack/production.js
Normal file
20
ui/docs/webpack/production.js
Normal file
@ -0,0 +1,20 @@
|
||||
const path = require('path');
|
||||
|
||||
const plugins = require('./plugins');
|
||||
const base = require('./base');
|
||||
|
||||
module.exports = Object.assign(base, {
|
||||
plugins: base.plugins.concat([
|
||||
plugins['occurrence-order'],
|
||||
plugins['aggressive-merging'],
|
||||
plugins['uglify-js']
|
||||
])
|
||||
});
|
||||
|
||||
/*
|
||||
* Maybe add in the future:
|
||||
* - https://github.com/lettertwo/appcache-webpack-plugin
|
||||
* - https://github.com/NekR/offline-plugin
|
||||
* - https://github.com/goldhand/sw-precache-webpack-plugin
|
||||
* - https://github.com/Klathmon/imagemin-webpack-plugin
|
||||
*/
|
3106
ui/docs/yarn.lock
Normal file
3106
ui/docs/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,47 +1,41 @@
|
||||
{
|
||||
"name": "joyent-dashboard-ui",
|
||||
"name": "joyent-portal-ui",
|
||||
"version": "1.0.0",
|
||||
"license": "MPL2",
|
||||
"private": true,
|
||||
"license": "private",
|
||||
"main": "static/ui",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"start": "webpack-dev-server --config webpack/index.js",
|
||||
"start": "cd docs && npm start",
|
||||
"lint": "make lint",
|
||||
"test": "make test",
|
||||
"build": "NODE_ENV=production webpack --config webpack/index.js",
|
||||
"clean-static": "git check-ignore static/** | xargs rm",
|
||||
"build-docs-static": "sh scripts/build-docs-static.sh"
|
||||
"build": "babel src --out-dir dist --source-maps inline"
|
||||
},
|
||||
"dependencies": {
|
||||
"classnames": "^2.2.5",
|
||||
"color": "^1.0.1",
|
||||
"invariant": "^2.2.2",
|
||||
"lodash.find": "^4.6.0",
|
||||
"lodash.first": "^3.0.0",
|
||||
"lodash.flatten": "^4.4.0",
|
||||
"lodash.get": "^4.4.2",
|
||||
"lodash.isarray": "^4.0.0",
|
||||
"lodash.isfunction": "^3.0.8",
|
||||
"lodash.isstring": "^4.0.1",
|
||||
"lodash.isundefined": "^3.0.1",
|
||||
"param-case": "^2.1.0",
|
||||
"react": "^15.4.1",
|
||||
"react-a11y": "^0.3.3",
|
||||
"react-icons": "^2.2.1",
|
||||
"reduce-css-calc": "^1.3.0",
|
||||
"traverse": "^0.6.6"
|
||||
"styled-components": "^1.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ava": "^0.17.0",
|
||||
"babel-cli": "^6.18.0",
|
||||
"babel-core": "^6.18.2",
|
||||
"babel-eslint": "^7.1.1",
|
||||
"babel-loader": "^6.2.8",
|
||||
"babel-plugin-add-module-exports": "^0.2.1",
|
||||
"babel-plugin-syntax-async-functions": "^6.13.0",
|
||||
"babel-plugin-transform-object-rest-spread": "^6.19.0",
|
||||
"babel-preset-es2015": "^6.18.0",
|
||||
"babel-preset-react": "^6.16.0",
|
||||
"babel-register": "^6.18.0",
|
||||
"css-loader": "^0.26.1",
|
||||
"css-modules-require-hook": "^4.0.5",
|
||||
"dangerously-set-inner-html": "2.0.0",
|
||||
"enzyme": "^2.6.0",
|
||||
"eslint": "^3.11.1",
|
||||
@ -52,44 +46,20 @@
|
||||
"eslint-plugin-promise": "^3.4.0",
|
||||
"eslint-plugin-react": "^6.8.0",
|
||||
"eslint-plugin-standard": "^2.0.1",
|
||||
"extract-text-webpack-plugin": "^2.0.0-beta.4",
|
||||
"graceful-fs": "^4.1.11",
|
||||
"json-loader": "^0.5.4",
|
||||
"lodash.get": "^4.4.2",
|
||||
"memory-fs": "^0.3.0",
|
||||
"nyc": "^10.0.0",
|
||||
"param-case": "^2.1.0",
|
||||
"postcss-at-rules-variables": "0.0.26",
|
||||
"postcss-constants": "^0.2.0",
|
||||
"postcss-cssnext": "^2.9.0",
|
||||
"postcss-for": "^2.1.1",
|
||||
"postcss-functions": "^2.1.1",
|
||||
"postcss-import": "9.0.0",
|
||||
"postcss-loader": "^1.2.0",
|
||||
"postcss-mixins": "^5.4.0",
|
||||
"postcss-modules-values": "^1.2.2",
|
||||
"pre-commit": "^1.1.3",
|
||||
"raw-loader": "^0.5.1",
|
||||
"react-addons-test-utils": "^15.4.1",
|
||||
"react-dom": "^15.4.1",
|
||||
"react-hot-loader": "^3.0.0-beta.6",
|
||||
"react-router": "^4.0.0-alpha.4",
|
||||
"st": "^1.2.0",
|
||||
"style-loader": "^0.13.1",
|
||||
"stylelint": "^7.6.0",
|
||||
"stylelint-config-standard": "^15.0.0",
|
||||
"stylelint-webpack-plugin": "^0.4.0",
|
||||
"tap-xunit": "^1.4.0",
|
||||
"title-case": "^2.1.0",
|
||||
"webpack": "^2.1.0-beta.25",
|
||||
"webpack-dev-server": "^1.16.2",
|
||||
"webpack-shell-plugin": "^0.4.6"
|
||||
"stylelint-processor-styled-components": "^0.0.4",
|
||||
"tap-xunit": "^1.4.0"
|
||||
},
|
||||
"ava": {
|
||||
"failFast": true,
|
||||
"cache": false,
|
||||
"require": [
|
||||
"css-modules-require-hook/preset",
|
||||
"babel-register"
|
||||
],
|
||||
"babel": "inherit"
|
||||
|
@ -1,3 +0,0 @@
|
||||
echo $(pwd)
|
||||
# cp -r ../static/* ../docs/static/
|
||||
# mv ../docs/static/index.html ../docs/
|
@ -1,32 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const StyleLintPlugin = require('stylelint-webpack-plugin');
|
||||
const webpack = require('webpack');
|
||||
const MemoryFS = require('memory-fs');
|
||||
const config = require('../webpack/base');
|
||||
|
||||
const mfs = new MemoryFS();
|
||||
const compiler = webpack(Object.assign(config, {
|
||||
plugins: config.plugins.concat([
|
||||
new StyleLintPlugin({
|
||||
configFile: '.stylelintrc',
|
||||
files: [
|
||||
'**/*.css'
|
||||
],
|
||||
failOnError: true
|
||||
})
|
||||
])
|
||||
}));
|
||||
|
||||
mfs.mkdirpSync(config.output.path);
|
||||
compiler.outputFileSystem = mfs;
|
||||
|
||||
compiler.run((err, stats) => {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
|
||||
process.on('unhandledRejection', () => {
|
||||
process.exit(1);
|
||||
});
|
@ -1,10 +1,40 @@
|
||||
// TODO: use a checkbox
|
||||
|
||||
const classNames = require('classnames');
|
||||
const React = require('react');
|
||||
const styles = require('./style.css');
|
||||
const composers = require('../../shared/composers');
|
||||
const fns = require('../../shared/functions');
|
||||
const Styled = require('styled-components');
|
||||
|
||||
const Avatar = ({
|
||||
const {
|
||||
verticallyAlignCenter
|
||||
} = composers;
|
||||
|
||||
const {
|
||||
remcalc
|
||||
} = fns;
|
||||
|
||||
const {
|
||||
default: styled
|
||||
} = Styled;
|
||||
|
||||
const Picture = styled.img`
|
||||
${verticallyAlignCenter}
|
||||
max-width: 60%;
|
||||
`;
|
||||
|
||||
const Letter = styled.p`
|
||||
font-size: 2rem;
|
||||
`;
|
||||
|
||||
const Avatar = styled.div`
|
||||
border-radius: 50%;
|
||||
height: ${remcalc(50)};
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
width: ${remcalc(50)};
|
||||
`;
|
||||
|
||||
module.exports = ({
|
||||
alt,
|
||||
className,
|
||||
color,
|
||||
@ -16,46 +46,35 @@ const Avatar = ({
|
||||
srcset,
|
||||
style
|
||||
}) => {
|
||||
|
||||
const cn = classNames(
|
||||
className,
|
||||
styles.avatar
|
||||
);
|
||||
|
||||
style = {
|
||||
const _style = {
|
||||
...style,
|
||||
background: color
|
||||
};
|
||||
|
||||
const letter = name.split('')[0];
|
||||
const av = src ? (
|
||||
<img
|
||||
<Picture
|
||||
alt={alt || name}
|
||||
className={styles.picture}
|
||||
crossOrigin={crossorigin}
|
||||
longdesc={longdesc}
|
||||
sizes={sizes}
|
||||
src={src}
|
||||
srcSet={srcset}
|
||||
style={style}
|
||||
/>
|
||||
) : (
|
||||
<p
|
||||
className={styles.letter}
|
||||
style={style}
|
||||
>
|
||||
<Letter>
|
||||
{letter}
|
||||
</p>
|
||||
</Letter>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={cn} style={style}>
|
||||
<Avatar className={className} style={_style}>
|
||||
{av}
|
||||
</div>
|
||||
</Avatar>
|
||||
);
|
||||
};
|
||||
|
||||
Avatar.propTypes = {
|
||||
module.exports.propTypes = {
|
||||
alt: React.PropTypes.string,
|
||||
className: React.PropTypes.string,
|
||||
color: React.PropTypes.string,
|
||||
@ -67,7 +86,3 @@ Avatar.propTypes = {
|
||||
srcset: React.PropTypes.string,
|
||||
style: React.PropTypes.object
|
||||
};
|
||||
|
||||
module.exports = Avatar;
|
||||
|
||||
|
||||
|
@ -1,17 +0,0 @@
|
||||
.avatar {
|
||||
border-radius: 50%;
|
||||
height: remcalc(50);
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
width: remcalc(50);
|
||||
}
|
||||
|
||||
.letter {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.picture {
|
||||
composes: verticle_align_center from "../../shared/composers.css";
|
||||
max-width: 60%;
|
||||
}
|
12
ui/src/components/base/global.js
Normal file
12
ui/src/components/base/global.js
Normal file
@ -0,0 +1,12 @@
|
||||
const Styled = require('styled-components');
|
||||
|
||||
const {
|
||||
css
|
||||
} = Styled;
|
||||
|
||||
module.exports = css`
|
||||
html, body {
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
}
|
||||
`;
|
@ -1,28 +1,477 @@
|
||||
const React = require('react');
|
||||
const classNames = require('classnames');
|
||||
const styles = require('./style.css');
|
||||
const constants = require('../../shared/constants');
|
||||
const Styled = require('styled-components');
|
||||
|
||||
const Base = ({
|
||||
children,
|
||||
className,
|
||||
style
|
||||
}) => {
|
||||
const cn = classNames(
|
||||
className,
|
||||
styles.base
|
||||
);
|
||||
const {
|
||||
forms,
|
||||
links,
|
||||
tables,
|
||||
typography
|
||||
} = constants;
|
||||
|
||||
return (
|
||||
<div className={cn} style={style}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
const {
|
||||
default: styled
|
||||
} = Styled;
|
||||
|
||||
Base.propTypes = {
|
||||
children: React.PropTypes.node,
|
||||
className: React.PropTypes.string,
|
||||
style: React.PropTypes.object
|
||||
};
|
||||
module.exports = styled.div`
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
font-size: 1rem;
|
||||
line-height: 1.5;
|
||||
color: #373A3C;
|
||||
background-color: #FFFFFF;
|
||||
|
||||
module.exports = Base;
|
||||
/**************************************************************************
|
||||
* NORMALIZE.CSS *
|
||||
**************************************************************************/
|
||||
|
||||
& article,
|
||||
& aside,
|
||||
& details,
|
||||
& figcaption,
|
||||
& figure,
|
||||
& footer,
|
||||
& header,
|
||||
& main,
|
||||
& menu,
|
||||
& nav,
|
||||
& section,
|
||||
& summary {
|
||||
display: block;
|
||||
}
|
||||
|
||||
& audio,
|
||||
& canvas,
|
||||
& progress,
|
||||
& video {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
& audio:not([controls]) {
|
||||
display: none;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
& progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
& template,
|
||||
& [hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
& a {
|
||||
background-color: transparent;
|
||||
-webkit-text-decoration-skip: objects;
|
||||
}
|
||||
|
||||
& a:active,
|
||||
& a:hover {
|
||||
outline-width: 0;
|
||||
}
|
||||
|
||||
& abbr[title] {
|
||||
border-bottom: none;
|
||||
text-decoration: underline;
|
||||
text-decoration: underline dotted;
|
||||
}
|
||||
|
||||
& b,
|
||||
& strong {
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
& b,
|
||||
& strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
& dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
& h1 {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
|
||||
& mark {
|
||||
background-color: #ff0;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
& small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
& sub,
|
||||
& sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
& sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
& sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
& img {
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
& svg:not(:root) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
& code,
|
||||
& kbd,
|
||||
& pre,
|
||||
& samp {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
& figure {
|
||||
margin: 1em 40px;
|
||||
}
|
||||
|
||||
& hr {
|
||||
-webkit-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
& button,
|
||||
& input,
|
||||
& optgroup,
|
||||
& select,
|
||||
& textarea {
|
||||
font: inherit;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
& optgroup {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
& button,
|
||||
& input {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
& button,
|
||||
& select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
& button,
|
||||
& [type="button"],
|
||||
& [type="reset"],
|
||||
& [type="submit"] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
& button::-moz-focus-inner,
|
||||
& [type="button"]::-moz-focus-inner,
|
||||
& [type="reset"]::-moz-focus-inner,
|
||||
& [type="submit"]::-moz-focus-inner {
|
||||
border-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
& button:-moz-focusring,
|
||||
& [type="button"]:-moz-focusring,
|
||||
& [type="reset"]:-moz-focusring,
|
||||
& [type="submit"]:-moz-focusring {
|
||||
outline: 1px dotted ButtonText;
|
||||
}
|
||||
|
||||
& fieldset {
|
||||
border: 1px solid #c0c0c0;
|
||||
margin: 0 2px;
|
||||
padding: 0.35em 0.625em 0.75em;
|
||||
}
|
||||
|
||||
& legend {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
color: inherit;
|
||||
display: table;
|
||||
max-width: 100%;
|
||||
padding: 0;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
& textarea {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
& [type="checkbox"],
|
||||
& [type="radio"] {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
& [type="number"]::-webkit-inner-spin-button,
|
||||
& [type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
& [type="search"] {
|
||||
-webkit-appearance: textfield;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
& [type="search"]::-webkit-search-cancel-button,
|
||||
& [type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
& ::-webkit-input-placeholder {
|
||||
color: inherit;
|
||||
opacity: 0.54;
|
||||
}
|
||||
|
||||
& ::-webkit-file-upload-button {
|
||||
-webkit-appearance: button;
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* BOOTSTRAP REBOOT *
|
||||
**************************************************************************/
|
||||
|
||||
& *,
|
||||
& *::before,
|
||||
& *::after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
& @-ms-viewport {
|
||||
width: device-width;
|
||||
}
|
||||
& [tabindex="-1"]:focus {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* Typography
|
||||
*/
|
||||
|
||||
& h1,
|
||||
& h2,
|
||||
& h3,
|
||||
& h4,
|
||||
& h5,
|
||||
& h6 {
|
||||
margin-top: 0;
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
|
||||
& p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
& abbr[title],
|
||||
& abbr[data-original-title] {
|
||||
cursor: help;
|
||||
border-bottom: 1px dotted ${typography.abbrBorderColor};
|
||||
}
|
||||
|
||||
& address {
|
||||
margin-bottom: 1rem;
|
||||
font-style: normal;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
& ol,
|
||||
& ul,
|
||||
& dl {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
& ol ol,
|
||||
& ul ul,
|
||||
& ol ul,
|
||||
& ul ol {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
& dt {
|
||||
font-weight: ${typography.dtFontWeight};
|
||||
}
|
||||
|
||||
& dd {
|
||||
margin-bottom: .5rem;
|
||||
margin-left: 0; /* Undo browser default */
|
||||
}
|
||||
|
||||
& blockquote {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Links
|
||||
*/
|
||||
|
||||
& a {
|
||||
color: ${links.color};
|
||||
text-decoration: ${links.decoration};
|
||||
|
||||
&:focus,
|
||||
&:hover {
|
||||
color: ${links.hoverColor};
|
||||
text-decoration: ${links.hoverDecoration};
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: 5px auto -webkit-focus-ring-color;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
}
|
||||
|
||||
& a:not([href]):not([tabindex]) {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
|
||||
&:focus,
|
||||
&:hover {
|
||||
color: ${links.hoverColor};
|
||||
text-decoration: ${links.hoverDecoration};
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Code
|
||||
*/
|
||||
|
||||
& pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Figures
|
||||
*/
|
||||
|
||||
& figure {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Images
|
||||
*/
|
||||
|
||||
& img {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
& [role="button"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
& a,
|
||||
& area,
|
||||
& button,
|
||||
& [role="button"],
|
||||
& input,
|
||||
& label,
|
||||
& select,
|
||||
& summary,
|
||||
& textarea {
|
||||
touch-action: manipulation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tables
|
||||
*/
|
||||
|
||||
& table {
|
||||
border-collapse: collapse;
|
||||
background-color: ${tables.bg};
|
||||
}
|
||||
|
||||
& caption {
|
||||
padding-top: ${tables.cellPadding};
|
||||
padding-bottom: ${tables.cellPadding};
|
||||
color: ${typography.textMuted};
|
||||
text-align: left;
|
||||
caption-side: bottom;
|
||||
}
|
||||
|
||||
& th {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forms
|
||||
*/
|
||||
|
||||
& label {
|
||||
display: inline-block;
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
|
||||
& button:focus {
|
||||
outline: 1px dotted;
|
||||
outline: 5px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
& input,
|
||||
& button,
|
||||
& select,
|
||||
& textarea {
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
& input[type="radio"],
|
||||
& input[type="checkbox"] {
|
||||
&:disabled {
|
||||
cursor: ${forms.cursorDisabled};
|
||||
}
|
||||
}
|
||||
|
||||
& input[type="date"],
|
||||
& input[type="time"],
|
||||
& input[type="datetime-local"],
|
||||
& input[type="month"] {
|
||||
-webkit-appearance: listbox;
|
||||
}
|
||||
|
||||
& textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
& fieldset {
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
& legend {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin-bottom: .5rem;
|
||||
font-size: 1.5rem;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
& input[type="search"] {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
`;
|
||||
|
@ -1,610 +0,0 @@
|
||||
/* from:
|
||||
*
|
||||
* reboot.css v4.0.0-alpha.5
|
||||
* MIT License
|
||||
* github.com/twbs/bootstrap
|
||||
*
|
||||
* normalize.css v4.2.0
|
||||
* MIT License
|
||||
* github.com/necolas/normalize.css
|
||||
*/
|
||||
|
||||
~forms: "../../shared/constants.js";
|
||||
~links: "../../shared/constants.js";
|
||||
~tables: "../../shared/constants.js";
|
||||
~typography: "../../shared/constants.js";
|
||||
|
||||
:root {
|
||||
--cursor-disabled: ~forms.cursorDisabled;
|
||||
--link-color: ~links.linkColor;
|
||||
--link-decoration: ~links.linkDecoration;
|
||||
--link-hover-color: ~links.linkHoverColor;
|
||||
--link-hover-decoration: ~links.linkHoverDecoration;
|
||||
--table-bg: ~tables.tableBg;
|
||||
--table-cell-padding: ~tables.tableCellPadding;
|
||||
--dt-font-weight: ~typography.dtFontWeight;
|
||||
--text-muted: ~typography.textMuted;
|
||||
--abbr-border-color: ~typography.abbrBorderColor;
|
||||
}
|
||||
|
||||
.base {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
font-size: 1rem;
|
||||
line-height: 1.5;
|
||||
color: #373A3C;
|
||||
background-color: #FFFFFF;
|
||||
|
||||
& :global {
|
||||
|
||||
/**************************************************************************
|
||||
* NORMALIZE.CSS *
|
||||
**************************************************************************/
|
||||
|
||||
& article,
|
||||
& aside,
|
||||
& details,
|
||||
& figcaption,
|
||||
& figure,
|
||||
& footer,
|
||||
& header,
|
||||
& main,
|
||||
& menu,
|
||||
& nav,
|
||||
& section,
|
||||
& summary {
|
||||
display: block;
|
||||
}
|
||||
|
||||
& audio,
|
||||
& canvas,
|
||||
& progress,
|
||||
& video {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
& audio:not([controls]) {
|
||||
display: none;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
& progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
& template,
|
||||
& [hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
& a {
|
||||
background-color: transparent;
|
||||
-webkit-text-decoration-skip: objects;
|
||||
}
|
||||
|
||||
& a:active,
|
||||
& a:hover {
|
||||
outline-width: 0;
|
||||
}
|
||||
|
||||
& abbr[title] {
|
||||
border-bottom: none;
|
||||
text-decoration: underline;
|
||||
text-decoration: underline dotted;
|
||||
}
|
||||
|
||||
& b,
|
||||
& strong {
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
& b,
|
||||
& strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
& dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
& h1 {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
|
||||
& mark {
|
||||
background-color: #ff0;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
& small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
& sub,
|
||||
& sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
& sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
& sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
& img {
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
& svg:not(:root) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
& code,
|
||||
& kbd,
|
||||
& pre,
|
||||
& samp {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
& figure {
|
||||
margin: 1em 40px;
|
||||
}
|
||||
|
||||
& hr {
|
||||
-webkit-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
& button,
|
||||
& input,
|
||||
& optgroup,
|
||||
& select,
|
||||
& textarea {
|
||||
font: inherit;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
& optgroup {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
& button,
|
||||
& input {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
& button,
|
||||
& select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
& button,
|
||||
& [type="button"],
|
||||
& [type="reset"],
|
||||
& [type="submit"] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
& button::-moz-focus-inner,
|
||||
& [type="button"]::-moz-focus-inner,
|
||||
& [type="reset"]::-moz-focus-inner,
|
||||
& [type="submit"]::-moz-focus-inner {
|
||||
border-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
& button:-moz-focusring,
|
||||
& [type="button"]:-moz-focusring,
|
||||
& [type="reset"]:-moz-focusring,
|
||||
& [type="submit"]:-moz-focusring {
|
||||
outline: 1px dotted ButtonText;
|
||||
}
|
||||
|
||||
& fieldset {
|
||||
border: 1px solid #c0c0c0;
|
||||
margin: 0 2px;
|
||||
padding: 0.35em 0.625em 0.75em;
|
||||
}
|
||||
|
||||
& legend {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
color: inherit;
|
||||
display: table;
|
||||
max-width: 100%;
|
||||
padding: 0;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
& textarea {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
& [type="checkbox"],
|
||||
& [type="radio"] {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
& [type="number"]::-webkit-inner-spin-button,
|
||||
& [type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
& [type="search"] {
|
||||
-webkit-appearance: textfield;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
& [type="search"]::-webkit-search-cancel-button,
|
||||
& [type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
& ::-webkit-input-placeholder {
|
||||
color: inherit;
|
||||
opacity: 0.54;
|
||||
}
|
||||
|
||||
& ::-webkit-file-upload-button {
|
||||
-webkit-appearance: button;
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* BOOTSTRAP REBOOT *
|
||||
**************************************************************************/
|
||||
|
||||
& *,
|
||||
& *::before,
|
||||
& *::after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
& @-ms-viewport {
|
||||
width: device-width;
|
||||
}
|
||||
|
||||
/*
|
||||
* Suppress the focus outline on elements that cannot be accessed via keyboard.
|
||||
* This prevents an unwanted focus outline from appearing around elements that
|
||||
* might still respond to pointer events.
|
||||
*
|
||||
* Credit: https://github.com/suitcss/base
|
||||
*/
|
||||
& [tabindex="-1"]:focus {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* Typography
|
||||
*/
|
||||
|
||||
/* Remove top margins from headings
|
||||
*
|
||||
* By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top
|
||||
* margin for easier control within type scales as it avoids margin collapsing.
|
||||
*/
|
||||
& h1,
|
||||
& h2,
|
||||
& h3,
|
||||
& h4,
|
||||
& h5,
|
||||
& h6 {
|
||||
margin-top: 0;
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
|
||||
/* Reset margins on paragraphs
|
||||
*
|
||||
* Similarly, the top margin on `<p>`s get reset. However, we also reset the
|
||||
* bottom margin to use `rem` units instead of `em`.
|
||||
*/
|
||||
& p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
/* Abbreviations and acronyms */
|
||||
& abbr[title],
|
||||
/* Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257 */
|
||||
& abbr[data-original-title] {
|
||||
cursor: help;
|
||||
border-bottom: 1px dotted var(--abbr-border-color);
|
||||
}
|
||||
|
||||
& address {
|
||||
margin-bottom: 1rem;
|
||||
font-style: normal;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
& ol,
|
||||
& ul,
|
||||
& dl {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
& ol ol,
|
||||
& ul ul,
|
||||
& ol ul,
|
||||
& ul ol {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
& dt {
|
||||
font-weight: var(--dt-font-weight);
|
||||
}
|
||||
|
||||
& dd {
|
||||
margin-bottom: .5rem;
|
||||
margin-left: 0; /* Undo browser default */
|
||||
}
|
||||
|
||||
& blockquote {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Links
|
||||
*/
|
||||
|
||||
& a {
|
||||
color: var(--link-color);
|
||||
text-decoration: var(--link-decoration);
|
||||
|
||||
&:focus,
|
||||
&:hover {
|
||||
color: var(--link-hover-color);
|
||||
text-decoration: var(--link-hover-decoration);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: 5px auto -webkit-focus-ring-color;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
}
|
||||
|
||||
/* And undo these styles for placeholder links/named anchors (without href)
|
||||
* which have not been made explicitly keyboard-focusable (without tabindex).
|
||||
* It would be more straightforward to just use a[href] in previous block, but that
|
||||
* causes specificity issues in many other styles that are too complex to fix.
|
||||
* See https://github.com/twbs/bootstrap/issues/19402
|
||||
*/
|
||||
|
||||
& a:not([href]):not([tabindex]) {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
|
||||
&:focus,
|
||||
&:hover {
|
||||
color: var(--link-hover-color);
|
||||
text-decoration: var(--link-hover-decoration);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Code
|
||||
*/
|
||||
|
||||
& pre {
|
||||
/* Remove browser default top margin */
|
||||
margin-top: 0;
|
||||
/* Reset browser default of `1em` to use `rem`s */
|
||||
margin-bottom: 1rem;
|
||||
/* Normalize v4 removed this property, causing `<pre>` content to break out of wrapping code snippets */
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Figures
|
||||
*/
|
||||
|
||||
& figure {
|
||||
/* Normalize adds `margin` to `figure`s as browsers apply it inconsistently.
|
||||
* We reset that to create a better flow in-page.
|
||||
*/
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Images
|
||||
*/
|
||||
|
||||
& img {
|
||||
/* By default, `<img>`s are `inline-block`. This assumes that, and vertically
|
||||
* centers them. This won't apply should you reset them to `block` level.
|
||||
*/
|
||||
vertical-align: middle;
|
||||
/* Note: `<img>`s are deliberately not made responsive by default.
|
||||
* For the rationale behind this, see the comments on the `.img-fluid` class.
|
||||
*/
|
||||
}
|
||||
|
||||
/* iOS "clickable elements" fix for role="button"
|
||||
*
|
||||
* Fixes "clickability" issue (and more generally, the firing of events such as focus as well)
|
||||
* for traditionally non-focusable elements with role="button"
|
||||
* see https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
|
||||
*/
|
||||
|
||||
& [role="button"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Avoid 300ms click delay on touch devices that support the `touch-action` CSS property.
|
||||
*
|
||||
* In particular, unlike most other browsers, IE11+Edge on Windows 10 on touch devices and IE Mobile 10-11
|
||||
* DON'T remove the click delay when `<meta name="viewport" content="width=device-width">` is present.
|
||||
* However, they DO support removing the click delay via `touch-action: manipulation`.
|
||||
* See:
|
||||
* * https://v4-alpha.getbootstrap.com/content/reboot/#click-delay-optimization-for-touch
|
||||
* * http://caniuse.com/#feat=css-touch-action
|
||||
* * https://patrickhlauke.github.io/touch/tests/results/#suppressing-300ms-delay
|
||||
*/
|
||||
|
||||
& a,
|
||||
& area,
|
||||
& button,
|
||||
& [role="button"],
|
||||
& input,
|
||||
& label,
|
||||
& select,
|
||||
& summary,
|
||||
& textarea {
|
||||
touch-action: manipulation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tables
|
||||
*/
|
||||
|
||||
& table {
|
||||
/* No longer part of Normalize since v4 */
|
||||
border-collapse: collapse;
|
||||
/* Reset for nesting within parents with `background-color`. */
|
||||
background-color: var(--table-bg);
|
||||
}
|
||||
|
||||
& caption {
|
||||
padding-top: var(--table-cell-padding);
|
||||
padding-bottom: var(--table-cell-padding);
|
||||
color: var(--text-muted);
|
||||
text-align: left;
|
||||
caption-side: bottom;
|
||||
}
|
||||
|
||||
& th {
|
||||
/* Centered by default, but left-align-ed to match the `td`s below. */
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forms
|
||||
*/
|
||||
|
||||
& label {
|
||||
/* Allow labels to use `margin` for spacing. */
|
||||
display: inline-block;
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
|
||||
/* Work around a Firefox/IE bug where the transparent `button` background
|
||||
* results in a loss of the default `button` focus styles.
|
||||
*
|
||||
* Credit: https://github.com/suitcss/base/
|
||||
*/
|
||||
& button:focus {
|
||||
outline: 1px dotted;
|
||||
outline: 5px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
& input,
|
||||
& button,
|
||||
& select,
|
||||
& textarea {
|
||||
/* Normalize includes `font: inherit;`, so `font-family`. `font-size`, etc are */
|
||||
/* properly inherited. However, `line-height` isn't inherited there. */
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
& input[type="radio"],
|
||||
& input[type="checkbox"] {
|
||||
/* Apply a disabled cursor for radios and checkboxes.
|
||||
*
|
||||
* Note: Neither radios nor checkboxes can be readonly.
|
||||
*/
|
||||
&:disabled {
|
||||
cursor: var(--cursor-disabled);
|
||||
}
|
||||
}
|
||||
|
||||
& input[type="date"],
|
||||
& input[type="time"],
|
||||
& input[type="datetime-local"],
|
||||
& input[type="month"] {
|
||||
/* Remove the default appearance of temporal inputs to avoid a Mobile Safari
|
||||
* bug where setting a custom line-height prevents text from being vertically
|
||||
* centered within the input.
|
||||
*
|
||||
* Bug report: https://github.com/twbs/bootstrap/issues/11266
|
||||
*/
|
||||
-webkit-appearance: listbox;
|
||||
}
|
||||
|
||||
& textarea {
|
||||
/* Textareas should really only resize vertically so they don't break their (horizontal) containers. */
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
& fieldset {
|
||||
/* Chrome and Firefox set a `min-width: min-content;` on fieldsets,
|
||||
* so we reset that to ensure it behaves more like a standard block element.
|
||||
* See https://github.com/twbs/bootstrap/issues/12359.
|
||||
*/
|
||||
min-width: 0;
|
||||
/* Reset the default outline behavior of fieldsets so they don't affect page layout. */
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
& legend {
|
||||
/* Reset the entire legend element to match the `fieldset` */
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin-bottom: .5rem;
|
||||
font-size: 1.5rem;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
& input[type="search"] {
|
||||
/* This overrides the extra rounded corners on search inputs in iOS so that our
|
||||
* `.form-control` class can properly style them. Note that this cannot simply
|
||||
* be added to `.form-control` as it's not specific enough. For details, see
|
||||
* https://github.com/twbs/bootstrap/issues/11586.
|
||||
*/
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
/* todo: needed? */
|
||||
& output {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* Always hide an element with the `hidden` HTML attribute (from PureCSS). */
|
||||
& [hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* GOBAL HELPERS *
|
||||
**************************************************************************/
|
||||
& .clearfix {
|
||||
&::before,
|
||||
&::after {
|
||||
content: "";
|
||||
display: table;
|
||||
}
|
||||
|
||||
&::after {
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,15 @@
|
||||
const React = require('react');
|
||||
const classNames = require('classnames');
|
||||
const styles = require('./style.css');
|
||||
const Button = require('../button');
|
||||
const React = require('react');
|
||||
const Styled = require('styled-components');
|
||||
|
||||
const {
|
||||
default: styled,
|
||||
css
|
||||
} = Styled;
|
||||
|
||||
const styles = css`
|
||||
font-size: inherit;
|
||||
`;
|
||||
|
||||
const ButtonIcon = ({
|
||||
name = 'beer',
|
||||
@ -9,18 +17,13 @@ const ButtonIcon = ({
|
||||
iconSet = 'fa',
|
||||
style
|
||||
}) => {
|
||||
|
||||
const Component = require(`react-icons/lib/${iconSet}/${name}`);
|
||||
|
||||
const cn = classNames(
|
||||
className,
|
||||
styles.icon
|
||||
);
|
||||
const Icon = require(`react-icons/lib/${iconSet}/${name}`);
|
||||
const Component = styled(Icon)(styles);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Button>
|
||||
<Component className={cn} style={style} />
|
||||
<Component className={className} style={style} />
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
|
@ -1,3 +0,0 @@
|
||||
.icon {
|
||||
font-size: inherit;
|
||||
}
|
@ -1,68 +1,59 @@
|
||||
const classNames = require('classnames');
|
||||
const React = require('react');
|
||||
const styles = require('./style.css');
|
||||
const constants = require('../../shared/constants');
|
||||
const fns = require('../../shared/functions');
|
||||
const match = require('../../shared/match');
|
||||
const Styled = require('styled-components');
|
||||
|
||||
const Button = ({
|
||||
autoFocus,
|
||||
children,
|
||||
className,
|
||||
disabled = false,
|
||||
form,
|
||||
formAction,
|
||||
formEncType,
|
||||
formMethod,
|
||||
formNoValidate,
|
||||
formTarget,
|
||||
name,
|
||||
secondary = false,
|
||||
style,
|
||||
type,
|
||||
value
|
||||
}) => {
|
||||
const cn = classNames(
|
||||
className,
|
||||
styles.button,
|
||||
secondary ? styles.secondary : styles.primary,
|
||||
disabled ? styles.inactive : '',
|
||||
);
|
||||
const {
|
||||
colors,
|
||||
boxes
|
||||
} = constants;
|
||||
|
||||
return (
|
||||
<button
|
||||
autoFocus={autoFocus}
|
||||
className={cn}
|
||||
disabled={disabled}
|
||||
form={form}
|
||||
formAction={formAction}
|
||||
formEncType={formEncType}
|
||||
formMethod={formMethod}
|
||||
formNoValidate={formNoValidate}
|
||||
formTarget={formTarget}
|
||||
name={name}
|
||||
style={style}
|
||||
type={type}
|
||||
value={value}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
const {
|
||||
remcalc
|
||||
} = fns;
|
||||
|
||||
const {
|
||||
default: styled,
|
||||
css
|
||||
} = Styled;
|
||||
|
||||
// TODO: this should come from constants
|
||||
// and be calculated accordingly
|
||||
const colors = {
|
||||
primaryBackground: colors.brandPrimary;
|
||||
primaryBorder: '#2532BB';
|
||||
primaryColor: '#FFFFFF';
|
||||
secondaryBackgroud: '#FFFFFF';
|
||||
secondaryBorder: '#D8D8D8';
|
||||
secondaryColor: '#646464';
|
||||
inactiveBackground: '#F9F9F9';
|
||||
inactiveBorder: '#D8D8D8';
|
||||
inactiveColor: '#737373';
|
||||
};
|
||||
|
||||
Button.propTypes = {
|
||||
autoFocus: React.PropTypes.bool,
|
||||
children: React.PropTypes.node,
|
||||
className: React.PropTypes.string,
|
||||
disabled: React.PropTypes.bool,
|
||||
form: React.PropTypes.string,
|
||||
formAction: React.PropTypes.string,
|
||||
formEncType: React.PropTypes.string,
|
||||
formMethod: React.PropTypes.string,
|
||||
formNoValidate: React.PropTypes.bool,
|
||||
formTarget: React.PropTypes.string,
|
||||
name: React.PropTypes.string,
|
||||
secondary: React.PropTypes.bool,
|
||||
style: React.PropTypes.object,
|
||||
type: React.PropTypes.string,
|
||||
value: React.PropTypes.string
|
||||
};
|
||||
const background = match({
|
||||
secondary: colors.secondaryBackgroud,
|
||||
inactive: colors.inactiveBackground
|
||||
}, colors.primaryBackground);
|
||||
|
||||
module.exports = Button;
|
||||
const border = match({
|
||||
secondary: colors.secondaryBorder,
|
||||
inactive: colors.inactiveBorder
|
||||
}, colors.primaryBorder);
|
||||
|
||||
const color = match({
|
||||
secondary: colors.secondaryColor,
|
||||
inactive: colors.inactiveColor
|
||||
}, colors.primaryColor);
|
||||
|
||||
module.exports = styled.button`
|
||||
border-radius: ${remcalc(boxes.borderRadius)};
|
||||
box-shadow: ${boxes.bottomShaddow};
|
||||
font-size: ${remcalc(16)};
|
||||
min-width: ${remcalc(120)};
|
||||
padding: ${remcalc(18 24)};
|
||||
|
||||
background: ${background};
|
||||
border: 1px solid ${border};
|
||||
color: ${color};
|
||||
`;
|
||||
|
@ -1,43 +0,0 @@
|
||||
~colors: "../../shared/constants.js";
|
||||
~boxes: "../../shared/constants.js";
|
||||
|
||||
:root {
|
||||
--primary-background: ~colors.brandPrimary;
|
||||
--primary-border: #2532BB;
|
||||
--primary-color: #FFFFFF;
|
||||
|
||||
--secondary-backgroud: #FFFFFF;
|
||||
--secondary-border: #D8D8D8;
|
||||
--secondary-color: #646464;
|
||||
|
||||
--inactive-background: #F9F9F9;
|
||||
--inactive-border: #D8D8D8;
|
||||
--inactive-color: #737373;
|
||||
}
|
||||
|
||||
@define-mixin button $background, $border-color, $color {
|
||||
background: $background;
|
||||
border: 1px solid $border-color;
|
||||
color: $color;
|
||||
}
|
||||
|
||||
.button {
|
||||
border-radius: remcalc(~boxes.borderRadius);
|
||||
box-shadow: ~boxes.bottomShaddow;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
font-size: remcalc(16);
|
||||
min-width: remcalc(120);
|
||||
padding: remcalc(18 24);
|
||||
|
||||
&.primary {
|
||||
@add-mixin button var(--primary-background), var(--primary-border), var(--primary-color);
|
||||
}
|
||||
|
||||
&.secondary {
|
||||
@add-mixin button var(--secondary-backgroud), var(--secondary-border), var(--secondary-color);
|
||||
}
|
||||
|
||||
&.inactive {
|
||||
@add-mixin button var(--inactive-background), var(--inactive-border), var(--inactive-color);
|
||||
}
|
||||
}
|
@ -3,62 +3,85 @@
|
||||
* 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 constants = require('../../shared/constants');
|
||||
const isUndefined = require('lodash.isundefined');
|
||||
const fns = require('../../shared/functions');
|
||||
const Styled = require('styled-components');
|
||||
|
||||
const breakpoints = [
|
||||
'xs',
|
||||
'sm',
|
||||
'md',
|
||||
'lg'
|
||||
];
|
||||
const {
|
||||
breakpoints,
|
||||
sizes
|
||||
} = constants;
|
||||
|
||||
const getClasses = (props) => {
|
||||
return flatten(breakpoints.map((size) => {
|
||||
const number = props[size];
|
||||
const offset = props[`${size}Offset`];
|
||||
const {
|
||||
calc
|
||||
} = fns;
|
||||
|
||||
return [
|
||||
number ? styles[`${size}-${number}`] : '',
|
||||
offset ? styles[`${size}-offset-${offset}`] : ''
|
||||
];
|
||||
})).filter(Boolean);
|
||||
const {
|
||||
default: styled,
|
||||
css
|
||||
} = Styled;
|
||||
|
||||
const padding = sizes.halfGutterWidth || '0.5rem';
|
||||
|
||||
const direction = (props) => props.reverse ? 'flex-direction' : 'row';
|
||||
|
||||
const width = (fallback) => (size) => (props) => {
|
||||
return !isUndefined(props[size])
|
||||
? calc(`(${props[size]} / ${sizes.gridColumns}) * 100%`)
|
||||
: fallback;
|
||||
};
|
||||
|
||||
const Column = (props) => {
|
||||
const {
|
||||
children,
|
||||
className,
|
||||
reverse,
|
||||
style
|
||||
} = props;
|
||||
const flexBasis = width('auto');
|
||||
const maxWidth = width('none');
|
||||
const marginLeft = width(0);
|
||||
|
||||
const cn = classNames(
|
||||
className,
|
||||
styles.column,
|
||||
reverse ? styles.reverse : '',
|
||||
...getClasses(props)
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={cn} style={style}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
const breakpoint = (prop, size) => {
|
||||
return (...args) => (props) => props[prop] && breakpoints[size](...args);
|
||||
};
|
||||
|
||||
Column.propTypes = {
|
||||
children: React.PropTypes.node,
|
||||
className: React.PropTypes.string,
|
||||
reverse: React.PropTypes.bool,
|
||||
style: React.PropTypes.object,
|
||||
...breakpoints.reduce((all, bp) => ({
|
||||
...all,
|
||||
[`${bp}Offset`]: React.PropTypes.number,
|
||||
[bp]: React.PropTypes.number
|
||||
}), {})
|
||||
};
|
||||
const sm = breakpoint('sm', 'small');
|
||||
const smOffset = breakpoint('smOffset', 'small');
|
||||
const md = breakpoint('md', 'medium');
|
||||
const mdOffset = breakpoint('mdOffset', 'medium');
|
||||
const lg = breakpoint('lg', 'large');
|
||||
const lgOffset = breakpoint('lgOffset', 'large');
|
||||
|
||||
module.exports = Column;
|
||||
module.exports = styled.div`
|
||||
box-sizing: border-box;
|
||||
flex: 0 0 auto;
|
||||
padding-left: ${padding};
|
||||
padding-right: ${padding};
|
||||
flex-grow: 1;
|
||||
|
||||
flex-basis: ${flexBasis('xs')};
|
||||
max-width: ${maxWidth('xs')};
|
||||
margin-left: ${marginLeft('xsOffset')};
|
||||
|
||||
${sm`
|
||||
flex-basis: ${flexBasis('sm')};
|
||||
max-width: ${maxWidth('sm')};
|
||||
`}
|
||||
|
||||
${smOffset`
|
||||
margin-left: ${marginLeft('smOffset')};
|
||||
`}
|
||||
|
||||
${md`
|
||||
flex-basis: ${flexBasis('md')};
|
||||
max-width: ${maxWidth('md')};
|
||||
`}
|
||||
|
||||
${mdOffset`
|
||||
margin-left: ${marginLeft('mdOffset')};
|
||||
`}
|
||||
|
||||
${lg`
|
||||
flex-basis: ${flexBasis('lg')};
|
||||
max-width: ${maxWidth('lg')};
|
||||
`}
|
||||
|
||||
${lgOffset`
|
||||
margin-left: ${marginLeft('lgOffset')};
|
||||
`}
|
||||
`;
|
||||
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* based on
|
||||
* https://github.com/kristoferjoseph/flexboxgrid/blob/master/dist/flexboxgrid.css
|
||||
*/
|
||||
|
||||
~sizes: "../../shared/constants.js";
|
||||
~breakpoints: "../../shared/constants.js";
|
||||
|
||||
:root {
|
||||
--half-gutter-width: ~sizes.halfGutterWidth;
|
||||
--grid-columns: 12; /* Cannot import values and use them within the loop */
|
||||
}
|
||||
|
||||
@custom-media --sm-viewport ~breakpoints.sm;
|
||||
@custom-media --md-viewport ~breakpoints.md;
|
||||
@custom-media --lg-viewport ~breakpoints.lg;
|
||||
|
||||
@define-mixin viewport $size {
|
||||
&.$(size) {
|
||||
flex-basis: 0;
|
||||
flex-grow: 1;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
@for $i from 1 to var(--grid-columns) {
|
||||
&.$(size)-$i {
|
||||
flex-basis: calc(($i / var(--grid-columns)) * 100%);
|
||||
max-width: calc(($i / var(--grid-columns)) * 100%);
|
||||
}
|
||||
}
|
||||
|
||||
@for $i from 0 to var(--grid-columns) {
|
||||
&.$(size)-offset-$i {
|
||||
margin-left: calc(($i / var(--grid-columns)) * 100%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.column {
|
||||
box-sizing: border-box;
|
||||
flex: 0 0 auto;
|
||||
padding-left: var(--half-gutter-width, 0.5rem);
|
||||
padding-right: 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;
|
||||
}
|
||||
}
|
@ -3,33 +3,39 @@
|
||||
* github.com/roylee0704/react-flexbox-grid/blob/master/src/components/Grid.js
|
||||
*/
|
||||
|
||||
const React = require('react');
|
||||
const classNames = require('classnames');
|
||||
const styles = require('./style.css');
|
||||
const constants = require('../../shared/constants')
|
||||
const Styled = require('styled-components');
|
||||
|
||||
const Container = ({
|
||||
fluid = false,
|
||||
className,
|
||||
children,
|
||||
style
|
||||
}) => {
|
||||
const cn = classNames(
|
||||
className,
|
||||
styles[fluid ? 'container-fluid' : 'container']
|
||||
);
|
||||
const {
|
||||
breakpoints,
|
||||
sizes
|
||||
} = constants;
|
||||
|
||||
return (
|
||||
<div className={cn} style={style}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
const {
|
||||
default: styled,
|
||||
css
|
||||
} = Styled;
|
||||
|
||||
Container.propTypes = {
|
||||
children: React.PropTypes.node,
|
||||
className: React.PropTypes.string,
|
||||
fluid: React.PropTypes.bool,
|
||||
style: React.PropTypes.object
|
||||
};
|
||||
const fluid = (props) => props.fluid && css`
|
||||
padding-left: ${sizes.outerMargin};
|
||||
padding-right: ${sizes.outerMargin};
|
||||
`;
|
||||
|
||||
module.exports = Container;
|
||||
module.exports = styled.div`
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
|
||||
${fluid}
|
||||
|
||||
${breakpoints.small`
|
||||
width: ${sizes.containerSm || '46rem'};
|
||||
`}
|
||||
|
||||
${breakpoints.medium`
|
||||
width: ${sizes.containerMd || '61rem'};
|
||||
`}
|
||||
|
||||
${breakpoints.large`
|
||||
width: ${sizes.containerLg || '71rem'};
|
||||
`}
|
||||
`;
|
||||
|
@ -1,3 +1 @@
|
||||
# `<Container>`
|
||||
|
||||
## usage
|
||||
|
@ -1,41 +0,0 @@
|
||||
/*
|
||||
* based on
|
||||
* https://github.com/kristoferjoseph/flexboxgrid/blob/master/dist/flexboxgrid.css
|
||||
*/
|
||||
|
||||
~sizes: "../../shared/constants.js";
|
||||
~breakpoints: "../../shared/constants.js";
|
||||
|
||||
:root {
|
||||
--outer-margin: ~sizes.outerMargin;
|
||||
--container-sm: ~sizes.containerSm;
|
||||
}
|
||||
|
||||
@custom-media --sm-viewport ~breakpoints.sm;
|
||||
@custom-media --md-viewport ~breakpoints.md;
|
||||
@custom-media --lg-viewport ~breakpoints.lg;
|
||||
|
||||
.container-fluid,
|
||||
.container {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.container-fluid {
|
||||
padding-left: var(--outer-margin);
|
||||
padding-right: var(--outer-margin);
|
||||
}
|
||||
|
||||
.container {
|
||||
@media ( --sm-viewport ) {
|
||||
width: var(--container-sm, 46rem);
|
||||
}
|
||||
|
||||
@media ( --md-viewport ) {
|
||||
width: var(--container-md, 61rem);
|
||||
}
|
||||
|
||||
@media ( --lg-viewport ) {
|
||||
width: var(--container-lg, 71rem);
|
||||
}
|
||||
}
|
@ -3,92 +3,87 @@
|
||||
* 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 constants = require('../../shared/constants');
|
||||
const match = require('../../shared/match');
|
||||
const sizeMatch = require('./size-match');
|
||||
const Styled = require('styled-components');
|
||||
|
||||
const breakpoints = [
|
||||
'xs',
|
||||
'sm',
|
||||
'md',
|
||||
'lg'
|
||||
];
|
||||
const {
|
||||
breakpoints,
|
||||
sizes
|
||||
} = constants;
|
||||
|
||||
const modifiers = [
|
||||
'start',
|
||||
'center',
|
||||
'end',
|
||||
'top',
|
||||
'middle',
|
||||
'bottom',
|
||||
'around',
|
||||
'between',
|
||||
'first',
|
||||
'last'
|
||||
];
|
||||
const {
|
||||
default: styled
|
||||
} = Styled;
|
||||
|
||||
const getClasses = (props) => {
|
||||
return flatten(modifiers.map((name) => {
|
||||
const value = props[name];
|
||||
const margin = sizes.gutterCompensation || '-0.5rem';
|
||||
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
const direction = (size) => match(sizeMatch(size, {
|
||||
reverse: 'row-reverse'
|
||||
}), 'row');
|
||||
|
||||
const bps = (() => {
|
||||
if (value === true) {
|
||||
return breakpoints;
|
||||
}
|
||||
const justify = (size) => match(sizeMatch(size, {
|
||||
center: 'center',
|
||||
end: 'flex-end',
|
||||
around: 'space-around',
|
||||
between: 'space-between'
|
||||
}), 'flex-start');
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
return value;
|
||||
}
|
||||
const textAlign = (size) => match(sizeMatch(size, {
|
||||
center: 'center',
|
||||
end: 'end'
|
||||
}), 'start');
|
||||
|
||||
return [value];
|
||||
})();
|
||||
const alignItems = (size) => match(sizeMatch(size, {
|
||||
top: 'flex-start',
|
||||
middle: 'center',
|
||||
bottom: 'flex-end'
|
||||
}), 'stretch');
|
||||
|
||||
return flatten(bps.map(bp => styles[`${name}-${bp}`]));
|
||||
})).filter(Boolean);
|
||||
};
|
||||
const order = (size) => match(sizeMatch(size, {
|
||||
first: -1,
|
||||
last: 1
|
||||
}), 0);
|
||||
|
||||
const Row = (props) => {
|
||||
const {
|
||||
className,
|
||||
reverse,
|
||||
children,
|
||||
style
|
||||
} = props;
|
||||
/**
|
||||
* ```html
|
||||
* <row center top={['xs', 'sm']} first='lg' />
|
||||
* ```
|
||||
**/
|
||||
module.exports = styled.div`
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex: 0 1 auto;
|
||||
flex-wrap: wrap;
|
||||
|
||||
const cn = classNames(
|
||||
className,
|
||||
styles.row,
|
||||
reverse ? styles.reverse : '',
|
||||
...getClasses(props)
|
||||
);
|
||||
margin-left: ${margin};
|
||||
margin-right: ${margin};
|
||||
|
||||
return (
|
||||
<div className={cn} style={style}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
flex-direction: ${direction('xs')};
|
||||
justify-content: ${justify('xs')};
|
||||
text-align: ${textAlign('xs')};
|
||||
align-items: ${alignItems('xs')};
|
||||
|
||||
const ModificatorType = React.PropTypes.oneOfType([
|
||||
React.PropTypes.bool,
|
||||
React.PropTypes.arrayOf(React.PropTypes.oneOf(breakpoints)),
|
||||
React.PropTypes.oneOf(breakpoints)
|
||||
]);
|
||||
${breakpoints.small`
|
||||
flex-direction: ${direction('sm')};
|
||||
justify-content: ${justify('sm')};
|
||||
text-align: ${textAlign('sm')};
|
||||
align-items: ${alignItems('sm')};
|
||||
|
||||
Row.propTypes = {
|
||||
children: React.PropTypes.node,
|
||||
className: React.PropTypes.string,
|
||||
reverse: React.PropTypes.bool,
|
||||
style: React.PropTypes.object,
|
||||
...modifiers.reduce((all, m) => ({
|
||||
...all,
|
||||
[m]: ModificatorType
|
||||
}), {})
|
||||
};
|
||||
`}
|
||||
|
||||
module.exports = Row;
|
||||
${breakpoints.medium`
|
||||
flex-direction: ${direction('md')};
|
||||
justify-content: ${justify('md')};
|
||||
text-align: ${textAlign('md')};
|
||||
align-items: ${alignItems('md')};
|
||||
`}
|
||||
|
||||
${breakpoints.large`
|
||||
flex-direction: ${direction('lg')};
|
||||
justify-content: ${justify('lg')};
|
||||
text-align: ${textAlign('lg')};
|
||||
align-items: ${alignItems('lg')};
|
||||
`}
|
||||
`;
|
||||
|
@ -3,16 +3,18 @@
|
||||
## demo
|
||||
|
||||
```embed
|
||||
const styleSheet = require('styled-components/lib/models/StyleSheet')
|
||||
const React = require('react');
|
||||
const ReactDOM = require('react-dom/server');
|
||||
const Row = require('./index.js');
|
||||
const Container = require('../container');
|
||||
const Button = require('../button');
|
||||
// const styles = styleSheet.rules().map(rule => rule.cssText).join('\n')
|
||||
|
||||
nmodule.exports = ReactDOM.renderToString(
|
||||
<Row center='xs' start='sm'>
|
||||
<Button>1</Button>
|
||||
<Button>2</Button>
|
||||
<pre>{styleSheet}</pre>
|
||||
<button>1</button>
|
||||
<button>2</button>
|
||||
</Row>
|
||||
);
|
||||
```
|
||||
|
27
ui/src/components/row/size-apply.js
Normal file
27
ui/src/components/row/size-apply.js
Normal file
@ -0,0 +1,27 @@
|
||||
const isArray = require('lodash.isarray');
|
||||
const isString = require('lodash.isstring');
|
||||
|
||||
/**
|
||||
* given a size, a prop and a value, we want to get that value
|
||||
* if the rule matches the size
|
||||
*
|
||||
* ```js
|
||||
* sizeApply('xs', 'xs', 'row-reverse'); //=> 'row-reverse'
|
||||
* sizeApply('xs', true, 'row-reverse'); //=> 'row-reverse'
|
||||
* sizeApply('xs', ['xs', 'sm'], 'row-reverse'); //=> 'row-reverse'
|
||||
* sizeApply('xs', 'sm', 'row-reverse'); //=> false
|
||||
* sizeApply('xs', false, 'row-reverse'); //=> false
|
||||
* sizeApply('xs', ['sm', 'lg'], 'row-reverse'); //=> false
|
||||
* ```
|
||||
**/
|
||||
module.exports = (size, prop, value) => {
|
||||
if (isString(prop) && prop === size) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (isArray(prop) && (prop.indexOf(size) >= 0)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return prop ? value : false;
|
||||
};
|
25
ui/src/components/row/size-match.js
Normal file
25
ui/src/components/row/size-match.js
Normal file
@ -0,0 +1,25 @@
|
||||
const sizeApply = require('./size-apply');
|
||||
|
||||
/**
|
||||
* this is the middle man between sizeApply and match. we want to turn an object
|
||||
* of {prop: value} into { prop: (props) => {} } so that each prop can only be
|
||||
* applied based on size
|
||||
*
|
||||
* ```js
|
||||
* sizeMatch('xs', {
|
||||
* center: 'center',
|
||||
* })
|
||||
*
|
||||
* // {
|
||||
* // center: (props) => sizeApply('xs', props['xs'], 'center')
|
||||
* // }
|
||||
* ```
|
||||
**/
|
||||
module.exports = (size, rules) => {
|
||||
return Object.keys(rules).reduce((acc, rule) => {
|
||||
return {
|
||||
...acc,
|
||||
[rule]: (props) => sizeApply(size, props[rule], rules[rule])
|
||||
};
|
||||
}, rules);
|
||||
};
|
@ -1,88 +0,0 @@
|
||||
/*
|
||||
* based on
|
||||
* https://github.com/kristoferjoseph/flexboxgrid/blob/master/dist/flexboxgrid.css
|
||||
*/
|
||||
|
||||
~sizes: "../../shared/constants.js";
|
||||
~breakpoints: "../../shared/constants.js";
|
||||
|
||||
:root {
|
||||
--gutter-compensation: ~sizes.gutterCompensation;
|
||||
}
|
||||
|
||||
@custom-media --sm-viewport ~breakpoints.sm;
|
||||
@custom-media --md-viewport ~breakpoints.md;
|
||||
@custom-media --lg-viewport ~breakpoints.lg;
|
||||
|
||||
@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-left: var(--gutter-compensation, -0.5rem);
|
||||
margin-right: 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;
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
module.exports = {
|
||||
'Getting Started': require('./getting-started.md'),
|
||||
Guidelines: {
|
||||
Overview: require('./guidelines/overview.md'),
|
||||
Layout: require('./guidelines/layout.md')
|
||||
},
|
||||
Components: {
|
||||
Avatar: require('./components/avatar/readme.md'),
|
||||
Base: require('./components/base/readme.md'),
|
||||
Container: require('./components/container/readme.md'),
|
||||
Row: require('./components/row/readme.md'),
|
||||
Input: require('./components/input/readme.md'),
|
||||
Icon: require('./components/icon/readme.md'),
|
||||
Radio: require('./components/radio/readme.md'),
|
||||
'Radio Group': require('./components/radio-group/readme.md'),
|
||||
Select: require('./components/select/readme.md'),
|
||||
Column: require('./components/column/readme.md'),
|
||||
Button: require('./components/button/readme.md'),
|
||||
'Button Icon': require('./components/button-icon/readme.md'),
|
||||
'Range Slider': require('./components/range-slider/readme.md'),
|
||||
Toggle: require('./components/toggle/readme.md'),
|
||||
Notificaton: require('./components/notification/readme.md'),
|
||||
Checkbox: require('./components/checkbox/readme.md'),
|
||||
Tab: require('./components/tabs/tab/readme.md'),
|
||||
Tabs: require('./components/tabs/readme.md'),
|
||||
Widget: require('./components/widget/readme.md'),
|
||||
Pagination: require('./components/pagination/readme.md'),
|
||||
Modal: require('./components/modal/readme.md')
|
||||
},
|
||||
FAQ: require('./faq.md')
|
||||
};
|
@ -1,23 +1,23 @@
|
||||
module.exports = {
|
||||
Avatar: require('./components/avatar'),
|
||||
// Avatar: require('./components/avatar'),
|
||||
Base: require('./components/base'),
|
||||
Button: require('./components/button'),
|
||||
ButtonIcon: require('./components/button-icon'),
|
||||
Checkbox: require('./components/checkbox'),
|
||||
// Button: require('./components/button'),
|
||||
// ButtonIcon: require('./components/button-icon'),
|
||||
// Checkbox: require('./components/checkbox'),
|
||||
Column: require('./components/column'),
|
||||
Container: require('./components/container'),
|
||||
Row: require('./components/row'),
|
||||
Tab: require('./components/tabs/tab'),
|
||||
Tabs: require('./components/tabs'),
|
||||
Toggle: require('./components/toggle'),
|
||||
Notificaton: require('./components/notification'),
|
||||
Input: require('./components/input'),
|
||||
Icon: require('./components/icon'),
|
||||
RangeSlider: require('./components/range-slider'),
|
||||
Radio: require('./components/radio'),
|
||||
RadioGroup: require('./components/radio-group'),
|
||||
Select: require('./components/select'),
|
||||
Widget: require('./components/widget'),
|
||||
Pagination: require('./components/pagination'),
|
||||
Modal: require('./components/modal')
|
||||
// Tab: require('./components/tabs/tab'),
|
||||
// Tabs: require('./components/tabs'),
|
||||
// Toggle: require('./components/toggle'),
|
||||
// Notificaton: require('./components/notification'),
|
||||
// Input: require('./components/input'),
|
||||
// Icon: require('./components/icon'),
|
||||
// RangeSlider: require('./components/range-slider'),
|
||||
// Radio: require('./components/radio'),
|
||||
// RadioGroup: require('./components/radio-group'),
|
||||
// Select: require('./components/select'),
|
||||
// Widget: require('./components/widget'),
|
||||
// Pagination: require('./components/pagination'),
|
||||
// Modal: require('./components/modal')
|
||||
};
|
||||
|
@ -1,11 +0,0 @@
|
||||
.verticle_align_center {
|
||||
/* Need to palce position:relative on parent */
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.clear {
|
||||
clear: both;
|
||||
}
|
20
ui/src/shared/composers.js
Normal file
20
ui/src/shared/composers.js
Normal file
@ -0,0 +1,20 @@
|
||||
const Styled = require('styled-components');
|
||||
|
||||
const {
|
||||
css
|
||||
} = Styled;
|
||||
|
||||
module.exports = {
|
||||
verticallyAlignCenter: css`
|
||||
/* Need to palce position:relative on parent */
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
`,
|
||||
clear: css`
|
||||
display: block;
|
||||
content: "";
|
||||
clear: both;
|
||||
`
|
||||
};
|
@ -1,15 +1,19 @@
|
||||
const styled = require('styled-components');
|
||||
|
||||
|
||||
const calc = require('reduce-css-calc');
|
||||
const traverse = require('traverse');
|
||||
const isFunction = require('lodash.isfunction');
|
||||
const Color = require('color');
|
||||
|
||||
const tables = {
|
||||
tableBg: 'transparent',
|
||||
tableCellPadding: '.75rem'
|
||||
bg: 'transparent',
|
||||
cellPadding: '.75rem'
|
||||
};
|
||||
|
||||
// github.com/kristoferjoseph/flexboxgrid/blob/master/dist/flexboxgrid.css
|
||||
const sizes = {
|
||||
gridColumns: 12,
|
||||
gutterWidth: '1rem',
|
||||
outerMargin: '2rem',
|
||||
gutterCompensation: ({
|
||||
@ -102,28 +106,38 @@ const typography = {
|
||||
};
|
||||
|
||||
const links = {
|
||||
linkColor: colors.brandPrimary,
|
||||
linkDecoration: 'none',
|
||||
linkHoverColor: ({
|
||||
linkColor
|
||||
color: colors.brandPrimary,
|
||||
decoration: 'none',
|
||||
hoverColor: ({
|
||||
color
|
||||
}) => {
|
||||
return Color(linkColor).darken(0.15).hex();
|
||||
return Color(color).darken(0.15).hex();
|
||||
},
|
||||
linkHoverDecoration: 'underline'
|
||||
hoverDecoration: 'underline'
|
||||
};
|
||||
|
||||
// github.com/kristoferjoseph/flexboxgrid/blob/master/dist/flexboxgrid.css
|
||||
const breakpoints = {
|
||||
const screens = {
|
||||
// >= 768px
|
||||
sm: 'only screen and (min-width: 48em)',
|
||||
small: 'only screen and (min-width: 48rem)',
|
||||
// >= 1024px
|
||||
md: 'only screen and (min-width: 64em)',
|
||||
medium: 'only screen and (min-width: 64rem)',
|
||||
// >= 1200px
|
||||
lg: 'only screen and (min-width: 75em)'
|
||||
large: 'only screen and (min-width: 75rem)'
|
||||
};
|
||||
|
||||
module.exports = traverse({
|
||||
breakpoints,
|
||||
const breakpoints = Object.keys(screens).reduce((acc, label) => {
|
||||
return {
|
||||
...acc,
|
||||
[label]: (...args) => styled.css`
|
||||
@media ${screens[label]} {
|
||||
${styled.css(...args)}
|
||||
}
|
||||
`
|
||||
};
|
||||
}, {});
|
||||
|
||||
const constants = traverse({
|
||||
colors,
|
||||
boxes,
|
||||
forms,
|
||||
@ -134,3 +148,8 @@ module.exports = traverse({
|
||||
}).map(function(x) {
|
||||
return isFunction(x) ? x(this.parent.node) : x;
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
...constants,
|
||||
breakpoints
|
||||
};
|
||||
|
@ -1,3 +1,5 @@
|
||||
const calc = require('reduce-css-calc');
|
||||
|
||||
module.exports = {
|
||||
remcalc: function(values) {
|
||||
values = values.replace('px', '').split(' ');
|
||||
@ -11,5 +13,8 @@ module.exports = {
|
||||
});
|
||||
|
||||
return outputRems;
|
||||
},
|
||||
calc: function(str) {
|
||||
return calc(`calc(${str})`);
|
||||
}
|
||||
};
|
||||
|
39
ui/src/shared/match.js
Normal file
39
ui/src/shared/match.js
Normal file
@ -0,0 +1,39 @@
|
||||
const find = require('lodash.find');
|
||||
const isFunction = require('lodash.isfunction');
|
||||
|
||||
/**
|
||||
* get values based on the props
|
||||
*
|
||||
* ```js
|
||||
* const matchable = match({
|
||||
* large: 20,
|
||||
* small: 10,
|
||||
* medium: (props) => props.isBlue ? 15 : false
|
||||
* }, 'initial');
|
||||
*
|
||||
* matchable({
|
||||
* large: true,
|
||||
* medium: true,
|
||||
* isBlue: true
|
||||
* }); //=> 20
|
||||
*
|
||||
* matchable({
|
||||
* isBlue: true
|
||||
* }); //=> 'initial'
|
||||
*
|
||||
* matchable({
|
||||
* isBlue: true,
|
||||
* medium: true
|
||||
* }); //=> 15
|
||||
* ```
|
||||
**/
|
||||
module.exports = (obj = {}, initial = '') => (props) => {
|
||||
const key = find(Object.keys(obj), (key) => props[key]);
|
||||
|
||||
if (!key) {
|
||||
return initial;
|
||||
}
|
||||
|
||||
const op = obj[key];
|
||||
return isFunction(op) ? op(props) : op;
|
||||
};
|
@ -1,13 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang='en-US'>
|
||||
<head>
|
||||
<title>Joyent UI Framework</title>
|
||||
<link href="css/theme.css" rel="stylesheet" type="text/css">
|
||||
<link href="css/reboot.css" rel="stylesheet" type="text/css">
|
||||
<link href="css/docs.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<div id='root'></div>
|
||||
<script src='js/docs.js'></script>
|
||||
</body>
|
||||
</html>
|
@ -1,4 +0,0 @@
|
||||
html, body {
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
}
|
200
ui/test/index.js
200
ui/test/index.js
@ -6,35 +6,35 @@ const {
|
||||
shallow
|
||||
} = enzyme;
|
||||
|
||||
test('renders <Avatar> without exploding', (t) => {
|
||||
const Avatar = require('../src/components/avatar');
|
||||
const wrapper = shallow(<Avatar />);
|
||||
t.deepEqual(wrapper.length, 1);
|
||||
});
|
||||
// test('renders <Avatar> without exploding', (t) => {
|
||||
// const Avatar = require('../src/components/avatar');
|
||||
// const wrapper = shallow(<Avatar />);
|
||||
// t.deepEqual(wrapper.length, 1);
|
||||
// });
|
||||
|
||||
test('renders <Base> without exploding', (t) => {
|
||||
const Base = require('../src/components/base');
|
||||
const wrapper = shallow(<Base />);
|
||||
t.deepEqual(wrapper.length, 1);
|
||||
});
|
||||
|
||||
test('renders <Button> without exploding', (t) => {
|
||||
const Button = require('../src/components/button');
|
||||
const wrapper = shallow(<Button />);
|
||||
t.deepEqual(wrapper.length, 1);
|
||||
});
|
||||
|
||||
test('renders <Checkbox> without exploding', (t) => {
|
||||
const Checkbox = require('../src/components/checkbox');
|
||||
const wrapper = shallow(<Checkbox />);
|
||||
t.deepEqual(wrapper.length, 1);
|
||||
});
|
||||
|
||||
test('renders <Column> without exploding', (t) => {
|
||||
const Column = require('../src/components/column');
|
||||
const wrapper = shallow(<Column />);
|
||||
t.deepEqual(wrapper.length, 1);
|
||||
});
|
||||
//
|
||||
// test('renders <Button> without exploding', (t) => {
|
||||
// const Button = require('../src/components/button');
|
||||
// const wrapper = shallow(<Button />);
|
||||
// t.deepEqual(wrapper.length, 1);
|
||||
// });
|
||||
//
|
||||
// test('renders <Checkbox> without exploding', (t) => {
|
||||
// const Checkbox = require('../src/components/checkbox');
|
||||
// const wrapper = shallow(<Checkbox />);
|
||||
// t.deepEqual(wrapper.length, 1);
|
||||
// });
|
||||
//
|
||||
// test('renders <Column> without exploding', (t) => {
|
||||
// const Column = require('../src/components/column');
|
||||
// const wrapper = shallow(<Column />);
|
||||
// t.deepEqual(wrapper.length, 1);
|
||||
// });
|
||||
|
||||
test('renders <Container> without exploding', (t) => {
|
||||
const Container = require('../src/components/container');
|
||||
@ -42,80 +42,80 @@ test('renders <Container> without exploding', (t) => {
|
||||
t.deepEqual(wrapper.length, 1);
|
||||
});
|
||||
|
||||
test('renders <Icon> without exploding', (t) => {
|
||||
const Icon = require('../src/components/icon');
|
||||
const wrapper = shallow(<Icon />);
|
||||
t.deepEqual(wrapper.length, 1);
|
||||
});
|
||||
|
||||
test('renders <Radio> without exploding', (t) => {
|
||||
const Radio = require('../src/components/radio');
|
||||
const wrapper = shallow(<Radio />);
|
||||
t.deepEqual(wrapper.length, 1);
|
||||
});
|
||||
|
||||
test('renders <RadioGroup> without exploding', (t) => {
|
||||
const RadioGroup = require('../src/components/radio-group');
|
||||
const wrapper = shallow(<RadioGroup />);
|
||||
t.deepEqual(wrapper.length, 1);
|
||||
});
|
||||
|
||||
test('renders <Row> without exploding', (t) => {
|
||||
const Row = require('../src/components/row');
|
||||
const wrapper = shallow(<Row />);
|
||||
t.deepEqual(wrapper.length, 1);
|
||||
});
|
||||
|
||||
test('renders <Tab> without exploding', (t) => {
|
||||
const Tab = require('../src/components/tabs/tab');
|
||||
const wrapper = shallow(<Tab />);
|
||||
t.deepEqual(wrapper.length, 1);
|
||||
});
|
||||
|
||||
test('renders <Tabs> without exploding', (t) => {
|
||||
const Tabs = require('../src/components/tabs');
|
||||
const wrapper = shallow(<Tabs />);
|
||||
t.deepEqual(wrapper.length, 1);
|
||||
});
|
||||
|
||||
test('renders <Toggle> without exploding', (t) => {
|
||||
const Toggle = require('../src/components/toggle');
|
||||
const wrapper = shallow(<Toggle />);
|
||||
t.deepEqual(wrapper.length, 1);
|
||||
});
|
||||
|
||||
test('renders <Widget> without exploding', (t) => {
|
||||
const Widget = require('../src/components/widget');
|
||||
const wrapper = shallow(<Widget />);
|
||||
t.deepEqual(wrapper.length, 1);
|
||||
});
|
||||
|
||||
test('renders <Input> without exploding', (t) => {
|
||||
const Input = require('../src/components/input');
|
||||
const wrapper = shallow(<Input />);
|
||||
t.deepEqual(wrapper.length, 1);
|
||||
});
|
||||
|
||||
test('renders <RangeSlider> without exploding', (t) => {
|
||||
const RangeSlider = require('../src/components/range-slider');
|
||||
const wrapper = shallow(<RangeSlider />);
|
||||
t.deepEqual(wrapper.length, 1);
|
||||
});
|
||||
|
||||
test('renders <Select> without exploding', (t) => {
|
||||
const Select = require('../src/components/select');
|
||||
const wrapper = shallow(<Select />);
|
||||
t.deepEqual(wrapper.length, 1);
|
||||
});
|
||||
|
||||
test('renders <Pagination> without exploding', (t) => {
|
||||
const Pagination = require('../src/components/pagination');
|
||||
const wrapper = shallow(<Pagination />);
|
||||
t.deepEqual(wrapper.length, 1);
|
||||
});
|
||||
|
||||
test('renders <Notification> without exploding', (t) => {
|
||||
const Pagination = require('../src/components/notification');
|
||||
const wrapper = shallow(<Pagination />);
|
||||
t.deepEqual(wrapper.length, 1);
|
||||
});
|
||||
// test('renders <Icon> without exploding', (t) => {
|
||||
// const Icon = require('../src/components/icon');
|
||||
// const wrapper = shallow(<Icon />);
|
||||
// t.deepEqual(wrapper.length, 1);
|
||||
// });
|
||||
//
|
||||
// test('renders <Radio> without exploding', (t) => {
|
||||
// const Radio = require('../src/components/radio');
|
||||
// const wrapper = shallow(<Radio />);
|
||||
// t.deepEqual(wrapper.length, 1);
|
||||
// });
|
||||
//
|
||||
// test('renders <RadioGroup> without exploding', (t) => {
|
||||
// const RadioGroup = require('../src/components/radio-group');
|
||||
// const wrapper = shallow(<RadioGroup />);
|
||||
// t.deepEqual(wrapper.length, 1);
|
||||
// });
|
||||
//
|
||||
// test('renders <Row> without exploding', (t) => {
|
||||
// const Row = require('../src/components/row');
|
||||
// const wrapper = shallow(<Row />);
|
||||
// t.deepEqual(wrapper.length, 1);
|
||||
// });
|
||||
//
|
||||
// test('renders <Tab> without exploding', (t) => {
|
||||
// const Tab = require('../src/components/tabs/tab');
|
||||
// const wrapper = shallow(<Tab />);
|
||||
// t.deepEqual(wrapper.length, 1);
|
||||
// });
|
||||
//
|
||||
// test('renders <Tabs> without exploding', (t) => {
|
||||
// const Tabs = require('../src/components/tabs');
|
||||
// const wrapper = shallow(<Tabs />);
|
||||
// t.deepEqual(wrapper.length, 1);
|
||||
// });
|
||||
//
|
||||
// test('renders <Toggle> without exploding', (t) => {
|
||||
// const Toggle = require('../src/components/toggle');
|
||||
// const wrapper = shallow(<Toggle />);
|
||||
// t.deepEqual(wrapper.length, 1);
|
||||
// });
|
||||
//
|
||||
// test('renders <Widget> without exploding', (t) => {
|
||||
// const Widget = require('../src/components/widget');
|
||||
// const wrapper = shallow(<Widget />);
|
||||
// t.deepEqual(wrapper.length, 1);
|
||||
// });
|
||||
//
|
||||
// test('renders <Input> without exploding', (t) => {
|
||||
// const Input = require('../src/components/input');
|
||||
// const wrapper = shallow(<Input />);
|
||||
// t.deepEqual(wrapper.length, 1);
|
||||
// });
|
||||
//
|
||||
// test('renders <RangeSlider> without exploding', (t) => {
|
||||
// const RangeSlider = require('../src/components/range-slider');
|
||||
// const wrapper = shallow(<RangeSlider />);
|
||||
// t.deepEqual(wrapper.length, 1);
|
||||
// });
|
||||
//
|
||||
// test('renders <Select> without exploding', (t) => {
|
||||
// const Select = require('../src/components/select');
|
||||
// const wrapper = shallow(<Select />);
|
||||
// t.deepEqual(wrapper.length, 1);
|
||||
// });
|
||||
//
|
||||
// test('renders <Pagination> without exploding', (t) => {
|
||||
// const Pagination = require('../src/components/pagination');
|
||||
// const wrapper = shallow(<Pagination />);
|
||||
// t.deepEqual(wrapper.length, 1);
|
||||
// });
|
||||
//
|
||||
// test('renders <Notification> without exploding', (t) => {
|
||||
// const Pagination = require('../src/components/notification');
|
||||
// const wrapper = shallow(<Pagination />);
|
||||
// t.deepEqual(wrapper.length, 1);
|
||||
// });
|
||||
|
@ -1,48 +0,0 @@
|
||||
const gracefulFs = require('graceful-fs');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
const plugins = require('./plugins');
|
||||
|
||||
const CONTEXT = path.join(__dirname, '../');
|
||||
const STATIC = path.join(__dirname, '../static');
|
||||
const SRC = path.join(__dirname, '../src');
|
||||
const DOCS = path.join(__dirname, '../docs');
|
||||
|
||||
// PATCH `fs` to avoid ENFILE errors
|
||||
gracefulFs.gracefulify(fs);
|
||||
|
||||
module.exports = {
|
||||
devtool: 'eval',
|
||||
context: CONTEXT,
|
||||
entry: path.join(SRC, 'index.js'),
|
||||
output: {
|
||||
path: STATIC,
|
||||
publicPath: '/',
|
||||
filename: '[name].js'
|
||||
},
|
||||
plugins: [
|
||||
plugins['no-errors'],
|
||||
plugins['extract-text'],
|
||||
plugins['loader-options']
|
||||
],
|
||||
module: {
|
||||
loaders: [{
|
||||
test: /js?$/,
|
||||
exclude: /node_modules/,
|
||||
include: [
|
||||
SRC,
|
||||
DOCS
|
||||
],
|
||||
loader: 'babel-loader'
|
||||
}, {
|
||||
test: /\.json?$/,
|
||||
exclude: /node_modules/,
|
||||
include: [
|
||||
SRC,
|
||||
DOCS
|
||||
],
|
||||
loader: 'json-loader'
|
||||
}]
|
||||
}
|
||||
};
|
@ -1,70 +0,0 @@
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin');
|
||||
const plugins = require('./plugins');
|
||||
const base = require('./base');
|
||||
const path = require('path');
|
||||
|
||||
const EmbedMarkdownLoader = path.join(__dirname, './embed-markdown-loader');
|
||||
const STATIC = path.join(__dirname, '../static');
|
||||
const SRC = path.join(__dirname, '../src');
|
||||
const DOCS = path.join(__dirname, '../docs');
|
||||
|
||||
const devServer = {
|
||||
contentBase: [
|
||||
STATIC
|
||||
],
|
||||
hot: true,
|
||||
compress: true,
|
||||
lazy: false,
|
||||
historyApiFallback: {
|
||||
index: './index.html'
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = Object.assign(base, {
|
||||
entry: {
|
||||
docs: [
|
||||
'react-hot-loader/patch',
|
||||
'webpack-dev-server/client?http://localhost:8080',
|
||||
'webpack/hot/only-dev-server',
|
||||
'./docs/index.js'
|
||||
]
|
||||
},
|
||||
resolveLoader: {
|
||||
alias: {
|
||||
'embed-markdown-loader': EmbedMarkdownLoader
|
||||
}
|
||||
},
|
||||
plugins: base.plugins.concat([
|
||||
plugins['named-modules'],
|
||||
plugins['hot-module-replacement'],
|
||||
plugins['define']
|
||||
]),
|
||||
module: Object.assign(base.module, {
|
||||
loaders: base.module.loaders.concat([{
|
||||
test: /\.md?$/,
|
||||
exclude: /node_modules/,
|
||||
include: [
|
||||
SRC,
|
||||
DOCS
|
||||
],
|
||||
loader: 'raw-loader!embed-markdown-loader'
|
||||
}, {
|
||||
test: /\.css?$/,
|
||||
exclude: /node_modules/,
|
||||
include: [
|
||||
SRC,
|
||||
DOCS
|
||||
],
|
||||
loader: ExtractTextPlugin.extract({
|
||||
fallbackLoader: 'style-loader',
|
||||
loader: [
|
||||
'css-loader?',
|
||||
'modules&importLoaders=1&',
|
||||
'localIdentName=[name]__[local]___[hash:base64:5]!',
|
||||
'postcss-loader'
|
||||
].join('')
|
||||
})
|
||||
}])
|
||||
}),
|
||||
devServer
|
||||
});
|
@ -1,21 +0,0 @@
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
const docs = path.join(__dirname, '../docs/index');
|
||||
const src = path.join(__dirname, '../src/components');
|
||||
const ui = path.join(__dirname, '../src/index.js');
|
||||
|
||||
module.exports = fs
|
||||
.readdirSync(src)
|
||||
.filter((entry) => fs.statSync(path.join(src, entry)).isDirectory())
|
||||
.map((entry) => ({
|
||||
name: entry,
|
||||
path: path.join(src, entry, './index.js')
|
||||
}))
|
||||
.concat([{
|
||||
name: 'docs',
|
||||
path: docs
|
||||
}, {
|
||||
name: 'ui',
|
||||
path: ui
|
||||
}]);
|
@ -1,48 +0,0 @@
|
||||
const path = require('path');
|
||||
|
||||
const plugins = require('./plugins');
|
||||
const base = require('./base');
|
||||
const entries = require('./entrypoints');
|
||||
|
||||
const SRC = path.join(__dirname, '../src');
|
||||
|
||||
module.exports = Object.assign(base, {
|
||||
output: Object.assign(base.output, {
|
||||
libraryTarget: 'commonjs2'
|
||||
}),
|
||||
entry: entries.filter((entry) => {
|
||||
return entry.name !== 'docs';
|
||||
}).reduce((all, entry) => {
|
||||
all[entry.name] = [`./${path.relative(base.context, entry.path)}`];
|
||||
return all;
|
||||
}, {}),
|
||||
plugins: base.plugins.concat([
|
||||
plugins['occurrence-order'],
|
||||
plugins['aggressive-merging'],
|
||||
plugins['uglify-js']
|
||||
]),
|
||||
module: Object.assign(base.module, {
|
||||
loaders: base.module.loaders.concat([{
|
||||
test: /\.css?$/,
|
||||
exclude: /node_modules/,
|
||||
include: [
|
||||
SRC
|
||||
],
|
||||
loader: [
|
||||
'style-loader!',
|
||||
'css-loader?',
|
||||
'modules&importLoaders=1&',
|
||||
'localIdentName=[name]__[local]___[hash:base64:5]!',
|
||||
'postcss-loader'
|
||||
].join('')
|
||||
}])
|
||||
})
|
||||
});
|
||||
|
||||
/*
|
||||
* Maybe add in the future:
|
||||
* - https://github.com/lettertwo/appcache-webpack-plugin
|
||||
* - https://github.com/NekR/offline-plugin
|
||||
* - https://github.com/goldhand/sw-precache-webpack-plugin
|
||||
* - https://github.com/Klathmon/imagemin-webpack-plugin
|
||||
*/
|
@ -1,22 +0,0 @@
|
||||
const plugins = require('./plugins');
|
||||
|
||||
module.exports = {
|
||||
output: {
|
||||
libraryTarget: 'commonjs2'
|
||||
},
|
||||
plugins: [
|
||||
plugins['no-errors'],
|
||||
plugins['loader-options']
|
||||
],
|
||||
module: {
|
||||
loaders: [{
|
||||
test: /\.css?$/,
|
||||
loader: [
|
||||
'css-loader?',
|
||||
'modules&importLoaders=1&',
|
||||
'localIdentName=[name]__[local]___[hash:base64:5]!',
|
||||
'postcss-loader'
|
||||
].join('')
|
||||
}]
|
||||
}
|
||||
};
|
2442
ui/yarn.lock
2442
ui/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user