smaller and simpler Card api (#821)

* feat(ui-toolkit): smaller and simpler Card api

fixes: #809
fixes: #777

* feat(ui-toolkit) - Make adjustments to header (#824)

* feat(ui-toolkit) - Make adjustments to header

* feat(ui-toolkit) - Make adjustments to header

* add issue and pull request templates (#819)

* feat(all) - Add issue and pull ruequest templates

* Update PULL_REQUEST_TEMPLATE.md

* Create COMMIT_GUIDELINES.md

* Update PULL_REQUEST_TEMPLATE.md

* Update PULL_REQUEST_TEMPLATE.md

* Update COMMIT_GUIDELINES.md

* feat(ui-toolkit): smaller and simpler Card api

fixes: #809
fixes: #777
This commit is contained in:
Sérgio Ramos 2017-10-31 10:03:44 +00:00 committed by Sara Vieira
parent f7eb8a276c
commit d84f972fbe
67 changed files with 2618 additions and 2346 deletions

View File

@ -1,3 +1,4 @@
packages/*/**
prototypes/*/**
artifacts
reports

View File

@ -1,6 +1,7 @@
{
"extends": "joyent-portal",
"rules": {
"jsx-a11y/href-no-hash": 0,
"new-cap": 0,
"no-console": 0
}

View File

@ -10,8 +10,8 @@
"format-staged": "./scripts/format --staged",
"lint-license": "./scripts/license-to-fail",
"lint-docs": "./scripts/quality-docs",
"lint-ci:root": "eslint scripts/*",
"lint:root": "eslint . --fix",
"lint-ci:root": "eslint . --ext .js --ext .md",
"lint:root": "eslint . --fix --ext .js --ext .md",
"lint-ci:packages": "lerna run lint-ci",
"lint:packages": "lerna run lint",
"lint-ci": "redrun -s lint-ci:*",
@ -20,19 +20,17 @@
"test": "lerna run test",
"clean": "lerna clean --yes",
"bootstrap": "lerna bootstrap",
"dev":
"lerna run dev --stream --parallel --scope my-joy-beta --scope cloudapi-gql",
"start":
"lerna run start --stream --parallel --scope my-joy-beta --scope cloudapi-gql",
"dev": "lerna run dev --stream --parallel --scope my-joy-beta --scope cloudapi-gql",
"start": "lerna run start --stream --parallel --scope my-joy-beta --scope cloudapi-gql",
"commitmsg": "commitlint -e",
"precommit": "cross-env CI=1 redrun -s lint-staged format-staged",
"postinstall": "lerna run prepublish",
"commit": "commit"
},
"devDependencies": {
"@commitlint/cli": "^3.2.0",
"@commitlint/config-angular": "^3.1.1",
"@commitlint/prompt-cli": "^3.2.0",
"@commitlint/cli": "^4.2.1",
"@commitlint/config-angular": "^4.2.1",
"@commitlint/prompt-cli": "^4.2.1",
"apr-awaitify": "^1.0.4",
"apr-filter": "^1.0.5",
"apr-for-each": "^1.0.6",
@ -40,36 +38,33 @@
"apr-map": "^1.0.5",
"apr-parallel": "^1.0.5",
"apr-reduce": "^1.0.5",
"babel-eslint": "^7.2.3",
"babel-eslint": "^8.0.1",
"checksum": "^0.1.1",
"cross-env": "^5.0.5",
"eslint": "^4.5.0",
"eslint-config-joyent-portal": "^3.0.0",
"eslint-config-prettier": "^2.3.0",
"eslint-config-react-app": "^2.0.0",
"eslint-config-xo-space": "^0.16.0",
"eslint-gh-status-reporter": "^1.0.7",
"eslint-plugin-flowtype": "^2.35.1",
"eslint-plugin-graphql": "^1.3.0",
"eslint-plugin-import": "^2.7.0",
"cross-env": "^5.1.0",
"eslint": "^4.9.0",
"eslint-config-joyent-portal": "^3.2.0",
"eslint-config-prettier": "^2.6.0",
"eslint-config-react-app": "^2.0.1",
"eslint-config-xo-space": "^0.17.0",
"eslint-plugin-flowtype": "^2.39.1",
"eslint-plugin-graphql": "^1.4.0-1",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-jsx-a11y": "^6.0.2",
"eslint-plugin-markdown": "^1.0.0-beta.6",
"eslint-plugin-prettier": "^2.2.0",
"eslint-plugin-react": "^7.3.0",
"eslint-plugin-prettier": "^2.3.1",
"eslint-plugin-react": "^7.4.0",
"execa": "^0.8.0",
"force-array": "^3.1.0",
"husky": "^0.14.3",
"lerna": "^2.1.2",
"lerna": "^2.4.0",
"license-to-fail": "^2.2.0",
"lighthouse-gh-status-reporter": "^1.0.12",
"lodash.uniq": "^4.5.0",
"prettier": "1.6.1",
"prettier": "1.7.4",
"quality-docs": "^3.3.0",
"read-pkg": "^2.0.0",
"redrun": "^5.9.17",
"redrun": "^5.9.18",
"staged-git-files": "0.0.4",
"stylelint-gh-status-reporter": "^1.0.7",
"yargs": "^8.0.2"
"yargs": "^10.0.3"
},
"workspaces": [
"packages/*",
@ -81,6 +76,7 @@
"lodash.defaults": "4.2.0",
"lodash.assign": "4.2.0",
"graphql": "0.11.7",
"isarray": "'2.0.2",
"moment": "2.19.1",
"codemirror": "5.30.0",
"react": "16.0.0",

View File

@ -2,6 +2,7 @@
"extends": "joyent-portal",
"plugins": ["graphql"],
"rules": {
"jsx-a11y/href-no-hash": 0,
"graphql/template-strings": ["error", {
"env": "apollo"
}],

View File

@ -19,7 +19,7 @@
"dependencies": {
"@2fd/graphdoc": "^2.4.0",
"apollo-errors": "^1.5.1",
"apollo-server-hapi": "^1.1.6",
"apollo-server-hapi": "^1.1.7",
"apr-awaitify": "^1.0.4",
"boom": "^6.0.0",
"bunyan": "^1.8.12",
@ -29,8 +29,8 @@
"good": "^7.3.0",
"good-console": "^6.4.0",
"good-squeeze": "^5.0.2",
"graphql-playground": "^1.0.8",
"graphql-tools": "^2.3.0",
"graphql-playground": "^1.0.33",
"graphql-tools": "^2.6.1",
"graphql-voyager": "^1.0.0-rc.9",
"hapi": "^16.6.2",
"hasha": "^3.0.0",
@ -41,10 +41,10 @@
"triton": "^5.4.0"
},
"devDependencies": {
"eslint": "^4.8.0",
"eslint-config-joyent-portal": "3.1.0",
"eslint": "^4.9.0",
"eslint-config-joyent-portal": "^3.2.0",
"eslint-plugin-graphql": "^1.4.0-1",
"graphql-faker": "^1.4.0",
"graphql-faker": "^1.5.0",
"nodemon": "^1.12.1",
"prettier": "^1.7.4"
},

View File

@ -7,6 +7,7 @@
// temp
"no-undef": 1,
"no-debugger": 1,
"no-negated-condition": 0
"no-negated-condition": 0,
"jsx-a11y/href-no-hash": 0
}
}

View File

@ -9,23 +9,21 @@
"dev": "REACT_APP_GQL_PORT=4000 PORT=3069 REACT_APP_GQL_PROTOCOL=http joyent-react-scripts start",
"start": "PORT=3069 joyent-react-scripts start",
"build": "NODE_ENV=production joyent-react-scripts build",
"lint:css": "stylelint './src/**/*.js'",
"lint:js": "eslint . --fix",
"lint": "redrun -s lint:*",
"test": "NODE_ENV=test ./test/run --env=jsdom",
"lint-ci": "eslint . --ext .js --ext .md && echo 0 `# stylelint './src/**/*.js'`",
"lint": "eslint . --fix --ext .js --ext .md && echo 0 `# stylelint './src/**/*.js'`",
"test-ci": "echo 0 `# NODE_ENV=test ./test/run --env=jsdom --coverage`",
"test": "NODE_ENV=test ./test/run --env=jsdom",
"prepublish": "echo 0"
},
"dependencies": {
"@manaflair/redux-batch": "^0.1.0",
"apollo": "^0.2.2",
"eslint-plugin-markdown": "^1.0.0-beta.6",
"joyent-ui-toolkit": "^2.0.0",
"joyent-ui-toolkit": "^2.0.1",
"lodash.find": "^4.6.0",
"lodash.get": "^4.4.2",
"lodash.isstring": "^4.0.1",
"lodash.sortby": "^4.7.0",
"lunr": "^2.1.3",
"lunr": "^2.1.4",
"moment": "^2.19.1",
"normalized-styled-components": "^1.0.17",
"param-case": "^2.1.1",
@ -33,7 +31,7 @@
"react": "^16.0.0",
"react-apollo": "^1.4.16",
"react-dom": "^16.0.0",
"react-json-view": "^1.13.0",
"react-json-view": "^1.13.1",
"react-redux": "^5.0.6",
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
@ -41,14 +39,14 @@
"redux-actions": "^2.2.1",
"redux-form": "^7.1.1",
"remcalc": "^1.0.9",
"styled-components": "^2.2.1",
"styled-components": "^2.2.2",
"title-case": "^2.1.1"
},
"devDependencies": {
"babel-plugin-inline-react-svg": "^0.4.0",
"babel-preset-joyent-portal": "^3.3.3",
"eslint": "^4.8.0",
"eslint-config-joyent-portal": "3.1.0",
"eslint": "^4.9.0",
"eslint-config-joyent-portal": "^3.2.0",
"jest": "^21.2.1",
"jest-alias-preprocessor": "^1.1.1",
"jest-cli": "^21.2.1",
@ -56,12 +54,12 @@
"jest-junit": "^3.1.0",
"jest-matcher-utils": "^21.2.1",
"jest-snapshot": "^21.2.1",
"jest-styled-components": "^4.7.0",
"jest-styled-components": "^4.9.0",
"jest-transform-graphql": "^2.1.0",
"joyent-react-scripts": "^2.2.1",
"joyent-react-scripts": "^2.6.0",
"react-test-renderer": "^16.0.0",
"redrun": "^5.9.18",
"serve": "^6.2.0",
"serve": "^6.3.1",
"stylelint": "^8.2.0",
"stylelint-config-joyent-portal": "^2.0.1"
}

View File

@ -16,12 +16,12 @@ export default ({
onCancel = () => {}
}) => {
const _error = error &&
!submitting && (
<Message error>
<MessageTitle>Ooops!</MessageTitle>
<MessageDescription>{error}</MessageDescription>
</Message>
);
!submitting && (
<Message error>
<MessageTitle>Ooops!</MessageTitle>
<MessageDescription>{error}</MessageDescription>
</Message>
);
return (
<form onSubmit={handleSubmit}>

View File

@ -8,10 +8,16 @@ import {
CardTitle,
CardLabel,
CardView,
CardOptions,
Checkbox,
FormGroup,
QueryBreakpoints,
StatusLoader
StatusLoader,
PopoverContainer,
PopoverTarget,
PopoverItem,
PopoverDivider,
Popover
} from 'joyent-ui-toolkit';
const { SmallOnly, Small } = QueryBreakpoints;
@ -65,6 +71,18 @@ export default ({ name, state, primary_ip, loading, last, first }) => (
</SmallOnly>
)}
</CardMeta>
<PopoverContainer clickable>
<PopoverTarget>
<CardOptions />
</PopoverTarget>
<Popover placement="right-start">
<PopoverItem>Scale</PopoverItem>
<PopoverItem>Restart</PopoverItem>
<PopoverItem>Stop</PopoverItem>
<PopoverDivider />
<PopoverItem>Delete</PopoverItem>
</Popover>
</PopoverContainer>
</CardView>
</Card>
);

View File

@ -86,12 +86,12 @@ export default ({
) : null;
const _error = error &&
!submitting && (
<Message error>
<MessageTitle>Ooops!</MessageTitle>
<MessageDescription>{error}</MessageDescription>
</Message>
);
!submitting && (
<Message error>
<MessageTitle>Ooops!</MessageTitle>
<MessageDescription>{error}</MessageDescription>
</Message>
);
return (
<form>

View File

@ -51,11 +51,11 @@ export default ({
const _snapshots = forceArray(snapshots);
const _loading = !_snapshots.length &&
loading && (
<ViewContainer center>
<StatusLoader />
</ViewContainer>
);
loading && (
<ViewContainer center>
<StatusLoader />
</ViewContainer>
);
const items = _snapshots.map((snapshot, i, all) => {
const { name } = snapshot;
@ -75,12 +75,12 @@ export default ({
});
const _error = error &&
!submitting && (
<Message error>
<MessageTitle>Ooops!</MessageTitle>
<MessageDescription>{error}</MessageDescription>
</Message>
);
!submitting && (
<Message error>
<MessageTitle>Ooops!</MessageTitle>
<MessageDescription>{error}</MessageDescription>
</Message>
);
return (
<form

View File

@ -34,20 +34,20 @@ const CreateSnapshot = ({
})(InstanceCreateSnapshot);
const _error = error &&
!instance &&
!_loading && (
<Message error>
<MessageTitle>Ooops!</MessageTitle>
<MessageDescription>
An error occurred while loading your instance
</MessageDescription>
</Message>
);
!instance &&
!_loading && (
<Message error>
<MessageTitle>Ooops!</MessageTitle>
<MessageDescription>
An error occurred while loading your instance
</MessageDescription>
</Message>
);
const _form = !loading &&
!_error && (
<CreateSnapshotForm onSubmit={handleSubmit} onCancel={handleCancel} />
);
!_error && (
<CreateSnapshotForm onSubmit={handleSubmit} onCancel={handleCancel} />
);
return (
<ViewContainer center={Boolean(_loading)} main>

View File

@ -43,15 +43,15 @@ const Snapshots = ({
const _loading = !_values.length && loading;
const _error = error &&
!_loading &&
!_values.length && (
<Message error>
<MessageTitle>Ooops!</MessageTitle>
<MessageDescription>
An error occurred while loading your instance snapshots
</MessageDescription>
</Message>
);
!_loading &&
!_values.length && (
<Message error>
<MessageTitle>Ooops!</MessageTitle>
<MessageDescription>
An error occurred while loading your instance snapshots
</MessageDescription>
</Message>
);
return (
<ViewContainer main>
@ -81,15 +81,13 @@ export default compose(
const { name } = variables;
const instance = find(get(rest, 'machines', []), ['name', name]);
const snapshots = get(
instance,
'snapshots',
[]
).map(({ created, updated, ...rest }) => ({
...rest,
created: moment.utc(created).unix(),
updated: moment.utc(updated).unix()
}));
const snapshots = get(instance, 'snapshots', []).map(
({ created, updated, ...rest }) => ({
...rest,
created: moment.utc(created).unix(),
updated: moment.utc(updated).unix()
})
);
const index = GenIndex(
snapshots.map(({ name, ...rest }) => ({ ...rest, id: name }))

View File

@ -24,15 +24,15 @@ const Summary = ({ instance, loading, error }) => {
const _summary = !_loading && instance && <ReactJson src={instance} />;
const _error = error &&
!_loading &&
!instance && (
<Message error>
<MessageTitle>Ooops!</MessageTitle>
<MessageDescription>
An error occurred while loading your instance summary
</MessageDescription>
</Message>
);
!_loading &&
!instance && (
<Message error>
<MessageTitle>Ooops!</MessageTitle>
<MessageDescription>
An error occurred while loading your instance summary
</MessageDescription>
</Message>
);
return (
<ViewContainer center={Boolean(_loading)} main>

View File

@ -1,6 +1,7 @@
{
"extends": "joyent-portal",
"rules": {
"no-console": 1,
"new-cap": 0,
"jsx-a11y/href-no-hash": 0
}

View File

@ -21,6 +21,7 @@ yarn add --dev joyent-portal-ui-toolkit
## Usage
```js
import React from 'react';
import { H1 } from 'joyent-portal-ui-toolkit';
export default () => <H1>Hello World</H1>;

View File

@ -1,4 +1,5 @@
@import url('https://fonts.googleapis.com/css?family=Roboto+Mono');
@import url('https://fonts.googleapis.com/css?family=Libre+Franklin');
body .rsg--sidebar-4 {
padding: 36px 30px;

View File

@ -1,25 +1,31 @@
{
"name": "joyent-ui-toolkit",
"version": "2.0.0",
"version": "2.0.1",
"license": "MPL-2.0",
"repository": "github:yldio/joyent-portal",
"main": "dist/umd/index.js",
"jsnext:main": "dist/es/index.js",
"module": "dist/es/index.js",
"scripts": {
"lint:css": "echo 0",
"lint:js": "eslint . --fix",
"lint": "redrun -s lint:*",
"lint-ci":
"eslint . --ext .js --ext .md && echo 0 `# stylelint './src/**/*.js'`",
"lint":
"eslint . --fix --ext .js --ext .md && echo 0 `# stylelint './src/**/*.js'`",
"test-ci": "echo 0",
"test": "echo 0",
"test:visual": "run-p serve jest",
"jest": "jest",
"serve": "http-server styleguide -p 6060 -s",
"copy-fonts": "rm -rf dist; mkdir -p dist/es/typography; mkdir -p dist/umd/typography; cp -r src/typography/libre-franklin dist/es/typography; cp -r src/typography/libre-franklin dist/umd/typography",
"compile-watch:es": "NODE_ENV=development babel src --out-dir dist/es --source-maps inline --watch",
"compile:es": "NODE_ENV=development babel src --out-dir dist/es --source-maps inline",
"compile:umd": "NODE_ENV=test babel src --out-dir dist/umd --source-maps inline",
"compile-watch:umd": "NODE_ENV=test babel src --out-dir dist/umd --source-maps inline --watch",
"copy-fonts":
"rm -rf dist; mkdir -p dist/es/typography; mkdir -p dist/umd/typography; cp -r src/typography/libre-franklin dist/es/typography; cp -r src/typography/libre-franklin dist/umd/typography",
"compile-watch:es":
"NODE_ENV=development babel src --out-dir dist/es --source-maps inline --watch",
"compile:es":
"NODE_ENV=development babel src --out-dir dist/es --source-maps inline",
"compile:umd":
"NODE_ENV=test babel src --out-dir dist/umd --source-maps inline",
"compile-watch:umd":
"NODE_ENV=test babel src --out-dir dist/umd --source-maps inline --watch",
"compile": "redrun -p compile:*",
"watch": "redrun copy-fonts && redrun -p compile-watch:*",
"styleguide:build": "NODE_ENV=production styleguidist build",
@ -40,66 +46,52 @@
"prop-types": "^15.6.0",
"react-bundle": "^1.0.4",
"react-input-range": "^1.2.1",
"react-popper": "^0.7.3",
"react-responsive": "^2.0.0",
"react-popper": "^0.7.4",
"react-responsive": "^3.0.0",
"react-styled-flexboxgrid": "^2.1.0",
"redrun": "^5.9.18",
"remcalc": "^1.0.9",
"rnd-id": "^1.1.1",
"styled-components": "^2.2.1",
"styled-components": "^2.2.2",
"styled-is": "^1.1.0",
"unitcalc": "^1.1.1"
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-inline-react-svg": "^0.4.0",
"babel-plugin-lodash": "^3.2.11",
"babel-plugin-transform-es3-member-expression-literals": "^6.22.0",
"babel-plugin-transform-es3-property-literals": "^6.22.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-joyent-portal": "^3.3.3",
"babel-preset-stage-0": "^6.24.1",
"chart.js": "^2.7.0",
"codemirror": "^5.30.0",
"css-loader": "^0.28.7",
"codemirror": "^5.31.0",
"eslint": "^4.9.0",
"eslint-config-joyent-portal": "3.1.0",
"file-loader": "^1.1.5",
"eslint-config-joyent-portal": "^3.2.0",
"http-server": "^0.10.0",
"jest": "^21.2.1",
"jest-diff": "^21.2.1",
"jest-image-snapshot": "^1.0.1",
"jest-matcher-utils": "^21.2.1",
"jest-snapshot": "^21.2.1",
"jest-styled-components": "^4.7.1",
"lodash-webpack-plugin": "^0.11.4",
"jest-styled-components": "^4.9.0",
"joyent-react-scripts": "^2.6.0",
"navalia": "^1.2.0",
"react": "^16.0.0",
"react-docgen": "^2.19.0",
"react-docgen": "^3.0.0-beta8",
"react-docgen-displayname-handler": "^1.0.1",
"react-dom": "^16.0.0",
"react-redux": "^5.0.6",
"react-router-dom": "^4.2.2",
"react-scripts": "^1.0.14",
"react-styleguidist": "^6.0.31",
"react-test-renderer": "^16.0.0",
"redux": "^3.7.2",
"redux-form": "^7.1.1",
"serve-static": "^1.13.1",
"snapguidist": "^2.1.0",
"style-loader": "^0.19.0",
"stylelint": "^8.2.0",
"stylelint-config-joyent-portal": "^2.0.1",
"svg-inline-loader": "^0.8.0",
"uglifyjs-webpack-plugin": "^1.0.0-beta.3",
"url-loader": "^0.6.2",
"webpack": "^3.8.1"
},
"peerDependencies": {
"chart.js": "^2.7.0",
"react": "^16.0.0",
"react-dom": "^16.0.0",
"react-router-dom": "^4.2.2",

View File

@ -65,7 +65,8 @@ accordingly.
#### examples
```
const Button = require('../button').default;
const React = require('react');
const { default: Button } = require('../button');
<span>
<Button marginRight='1'>margin-right: 1</Button>

View File

@ -2,18 +2,51 @@ import { css } from 'styled-components';
import remcalc from 'remcalc';
export const borderRadius = remcalc(4);
export const bottomShadow = `0 ${remcalc(2)} 0 0 rgba(0, 0, 0, 0.05)`;
export const bottomShadowDarker = `0 ${remcalc(2)} 0 0 rgba(0, 0, 0, 0.1)`;
export const insetShaddow = `inset 0 ${remcalc(3)} 0 0 rgba(0, 0, 0, 0.05)`;
export const tooltipShadow = `0 ${remcalc(2)} ${remcalc(6)} ${remcalc(
1
)} rgba(0, 0, 0, 0.1)`;
export const modalShadow = `0 0 ${remcalc(6)} ${remcalc(1)} rgba(0, 0, 0, 0.1)`;
export const bottomShadow = `
/* trick prettier */
0 ${remcalc(2)} 0 0 rgba(0, 0, 0, 0.05)
`;
export const bottomShadowDarker = `
/* trick prettier */
0 ${remcalc(2)} 0 0 rgba(0, 0, 0, 0.1)
`;
export const insetShadow = `
/* trick prettier */
inset 0 ${remcalc(3)} 0 0 rgba(0, 0, 0, 0.05)
`;
export const tooltipShadow = `
/* trick prettier */
0 ${remcalc(2)} ${remcalc(6)} ${remcalc(1)} rgba(0, 0, 0, 0.1)
`;
export const modalShadow = `
/* trick prettier */
0 0 ${remcalc(6)} ${remcalc(1)} rgba(0, 0, 0, 0.1)
`;
export const border = {
checked: css`${remcalc(1)} solid ${props => props.theme.primary};`,
unchecked: css`${remcalc(1)} solid ${props => props.theme.grey};`,
confirmed: css`${remcalc(1)} solid ${props => props.theme.grey};`,
error: css`${remcalc(1)} solid ${props => props.theme.red};`,
secondary: css`${remcalc(1)} solid ${props => props.theme.secondaryActive};`
checked: css`
/* trick prettier */
${remcalc(1)} solid ${props => props.theme.primary};
`,
unchecked: css`
/* trick prettier */
${remcalc(1)} solid ${props => props.theme.grey};
`,
confirmed: css`
/* trick prettier */
${remcalc(1)} solid ${props => props.theme.grey};
`,
error: css`
/* trick prettier */
${remcalc(1)} solid ${props => props.theme.red};
`,
secondary: css`
/* trick prettier */
${remcalc(1)} solid ${props => props.theme.secondaryActive};
`
};

View File

@ -1,6 +1,7 @@
```
const Breadcrumb = require('./index.js').default;
const BreadcrumbItem = require('./item.js').default;
const React = require('react');
const { default: Breadcrumb } = require('./index.js');
const { default: BreadcrumbItem } = require('./item.js');
<Breadcrumb>
<BreadcrumbItem>Home</BreadcrumbItem>

View File

@ -1,4 +1,7 @@
```jsx
const React = require('react');
const { default: Button } = require('./');
<span>
<Button>Inspire the lazy</Button>
<span> </span>
@ -9,6 +12,9 @@
#### Button > Secondary
```jsx
const React = require('react');
const { default: Button } = require('./');
<span>
<Button secondary>Inspire the brave</Button>
<span> </span>
@ -21,6 +27,9 @@
#### Button > Tertiary
```jsx
const React = require('react');
const { default: Button } = require('./');
<span>
<Button tertiary>Inspire the tertiary</Button>
<span> </span>
@ -37,6 +46,9 @@
#### Button > Disabled
```jsx
const React = require('react');
const { default: Button } = require('./');
<span>
<Button disabled>Inspire the liars</Button>
<span> </span>
@ -49,6 +61,9 @@
#### Button > Loading
```jsx
const React = require('react');
const { default: Button } = require('./');
<span>
<Button secondary loading>
Inspire the liars

View File

@ -1,12 +0,0 @@
import remcalc from 'remcalc';
import Title from './title';
export default Title.extend`
line-height: 1;
width: ${remcalc(24)};
padding-right: 0;
display: flex;
flex-direction: column;
justify-content: center;
flex: none;
`;

View File

@ -1,164 +1,135 @@
import { Broadcast, Subscriber } from 'joy-react-broadcast';
import Baseline from '../baseline';
import paperEffect from './paper-effect';
import { bottomShadow, bottomShadowDarker } from '../boxes';
import remcalc from 'remcalc';
import is, { isNot } from 'styled-is';
import { Row } from 'react-styled-flexboxgrid';
import PropTypes from 'prop-types';
import React from 'react';
import { Broadcast } from 'joy-react-broadcast';
import styled, { css } from 'styled-components';
import PropTypes from 'prop-types';
import is, { isNot } from 'styled-is';
import remcalc from 'remcalc';
const StyledCard = Row.extend`
position: relative;
height: auto;
min-height: ${remcalc(126)};
margin-bottom: ${remcalc(10)};
border: ${remcalc(1)} solid ${props => props.theme.grey};
background-color: ${props => props.theme.white};
box-shadow: ${bottomShadow};
import Baseline from '../baseline';
import { bottomShadow, bottomShadowDarker } from '../boxes';
const paperEffect = css`
margin-bottom: ${remcalc(16)};
box-shadow: 0 ${remcalc(8)} 0 ${remcalc(-5)}
${props => props.theme.background},
0 ${remcalc(8)} ${remcalc(1)} ${remcalc(-4)} ${props => props.theme.grey},
0 ${remcalc(16)} 0 ${remcalc(-10)} ${props => props.theme.background},
0 ${remcalc(16)} ${remcalc(1)} ${remcalc(-9)} ${props => props.theme.grey};
`;
export const BaseCard = styled.div`
box-sizing: content-box;
display: flex;
flex: 1 0 auto;
flex-direction: column;
margin-right: ${remcalc(0)};
margin-left: ${remcalc(0)};
height: auto;
min-height: ${remcalc(125)};
position: relative;
${is('collapsed')`
min-height: auto;
height: ${remcalc(48)};
margin-bottom: ${remcalc(16)};
margin-bottom: 0;
transition: all 300ms ease;
border-width: ${remcalc(1)};
border-style: solid;
/* primary */
color: ${props => props.theme.text};
background-color: ${props => props.theme.white};
border-color: ${props => props.theme.grey};
${is('shadow')`
/* primary */
box-shadow: ${bottomShadow};
/* if disabled, shadow is the same */
${isNot('disabled')`
${is('secondary')`
box-shadow: ${bottomShadowDarker};
`};
${is('tertiary')`
box-shadow: 0 ${remcalc(2)} 0 rgba(0, 0, 0, 0.05);
`};
${is('stacked')`
box-shadow: ${paperEffect};
`};
`};
`};
${is('collapsed', 'headed')`
box-shadow: ${bottomShadowDarker};
${is('secondary')`
color: ${props => props.theme.white};
background-color: ${props => props.theme.primary};
border-color: ${props => props.theme.primaryActive};
`};
${is('flat')`
box-shadow: none;
${is('tertiary')`
color: ${props => props.theme.text};
background-color: ${props => props.theme.background};
border-color: ${props => props.theme.grey};
border-radius: ${remcalc(4)};
min-width: ${remcalc(292)};
${is('active')`
border-color: ${props => props.theme.primary};
background: ${props => props.theme.tertiaryActive};
box-shadow: none;
`};
`};
${is('bottomless')`
border-bottom-width: 0;
height: ${remcalc(47)};
`};
${is('gapless')`
margin-bottom: 0;
`};
${is('topMargin')`
margin-top: ${remcalc(10)};
`};
${is('icon')`
background: url(${props => props.icon}) no-repeat scroll ${remcalc(
7
)} ${remcalc(7)};
padding-left: ${remcalc(30)};
`};
${is('transparent')`
border-radius: 4px;
border: 1px solid ${props => props.theme.grey};
background: ${props => props.theme.background};
box-shadow: 0px 2px 0px rgba(0, 0, 0, 0.05);
min-height: ${remcalc(185)};
min-width: 292px;
${is('actionable')`
cursor: pointer;
transition: all 300ms ease;
`};
${is('transparent', 'selected')`
border: 1px solid ${props => props.theme.primary};
background: ${props => props.theme.tertiaryActive};
box-shadow: none;
`};
${is('stacked')`
${paperEffect}
`};
${is('disabled')`
border-color: ${props => props.theme.grey};
background-color: ${props => props.theme.disabled};
color: ${props => props.theme.text};
cursor: default;
`};
${isNot('active')`
background-color: ${props => props.theme.disabled};
${is('collapsed')`
min-height: auto;
height: ${remcalc(46)};
flex: 0 0 ${remcalc(46)};
`};
`;
/**
* @example ./usage.md
* @example ./demo.md
*/
const Card = ({
children,
collapsed = false,
headed = false,
active = true,
...rest
}) => {
const render = value => {
const newValue = {
fromHeader: (value || {}).fromHeader,
headed,
collapsed,
active
};
return (
<Broadcast channel="card" value={newValue}>
<StyledCard
name="card"
active={active}
collapsed={collapsed}
headed={headed}
{...rest}
>
{children}
</StyledCard>
</Broadcast>
);
};
return <Subscriber channel="card">{render}</Subscriber>;
};
const Card = ({ children, ...rest }) => (
<Broadcast channel="card" value={rest}>
<BaseCard {...rest} name="card">
{children}
</BaseCard>
</Broadcast>
);
Card.propTypes = {
/**
* Contents of the Card
*/
children: PropTypes.node,
/**
* Is it collapsed ?
*/
secondary: PropTypes.bool,
tertiary: PropTypes.bool,
collapsed: PropTypes.bool,
/**
* Does it have a header
*/
headed: PropTypes.bool,
/**
* Setting this to true will remove the box shadow
*/
flat: PropTypes.bool,
/**
* If set to true a paper effect will be added
*/
disabled: PropTypes.bool,
stacked: PropTypes.bool,
/**
* Transparent will set the card as secondary
*/
transparent: PropTypes.bool,
/**
* When set to false or using disabled you will see the disabled card
*/
active: PropTypes.bool
active: PropTypes.bool,
shadow: PropTypes.bool,
actionable: PropTypes.bool
};
Card.defaultProps = {
children: null,
collapsed: false,
headed: false,
flat: false,
secondary: false,
tertiary: false,
disabled: false,
stacked: false,
transparent: false,
active: true
active: false,
shadow: false,
actionable: false
};
export default Baseline(Card);

View File

@ -0,0 +1,438 @@
```jsx
const React = require('react');
const { Card } = require('.');
<Card />;
```
#### Card > Shadow
```jsx
const React = require('react');
const { Card } = require('.');
<Card shadow />;
```
#### Card > Headed > Collapsed
```jsx
const React = require('react');
const { Card, Header, HeaderBox, HeaderMeta } = require('.');
const { Row, Col } = require('react-styled-flexboxgrid');
const { H4, P } = require('../text');
const {
InstancesIconLight,
IconActionsLight
} = require('../icons');
<Card shadow collapsed>
<Header>
<HeaderMeta>
<Row between="xs" middle="xs">
<Col xs={4} sm={9} md={10}>
<H4>Nginx</H4>
</Col>
<Col xs={8} sm={3} md={2}>
<P>
<InstancesIconLight marginRight="0.5" /> 4 of 4 instances
</P>
</Col>
</Row>
</HeaderMeta>
<HeaderBox border="left" actionable>
<IconActionsLight />
</HeaderBox>
</Header>
</Card>;
```
#### Card > Headed
```jsx
const React = require('react');
const { Card, Header, HeaderBox, HeaderMeta, Outlet } = require('.');
const { Row, Col } = require('react-styled-flexboxgrid');
const { H4, P } = require('../text');
const {
InstancesIconLight,
HealthyIcon,
IconActionsLight
} = require('../icons');
<Card shadow>
<Header>
<HeaderMeta>
<Row between="xs" middle="xs">
<Col xs={4} sm={9} md={10}>
<H4>Nginx</H4>
</Col>
<Col xs={8} sm={3} md={2}>
<P>
<InstancesIconLight marginRight="0.5" /> 4 of 4 instances
</P>
</Col>
</Row>
</HeaderMeta>
<HeaderBox border="left" actionable>
<IconActionsLight />
</HeaderBox>
</Header>
<Outlet>
<div
style={{
display: 'flex',
flex: '1 0 auto',
flexDirection: 'row',
alignSelf: 'stretch',
justifyContent: 'flex-end',
alignContent: 'stretch',
alignItems: 'stretch'
}}
>
<P style={{ flex: '1 0 auto', alignSelf: 'flex-end' }}>
<HealthyIcon width="18" /> Healthy
</P>
</div>
</Outlet>
</Card>;
```
#### Card > Single State
```jsx
const React = require('react');
const { Card, Header, HeaderBox, HeaderMeta, Outlet } = require('.');
const { Row, Col } = require('react-styled-flexboxgrid');
const { H4, P, Small } = require('../text');
const {
InstancesIconLight,
IconActionsLight
} = require('../icons');
<Card shadow>
<Header>
<HeaderMeta>
<Row between="xs" middle="xs">
<Col xs={4} sm={9} md={10}>
<H4>Nginx</H4>
</Col>
<Col xs={8} sm={3} md={2}>
<P>
<InstancesIconLight marginRight="0.5" /> 4 of 4 instances
</P>
</Col>
</Row>
</HeaderMeta>
<HeaderBox border="left" actionable>
<IconActionsLight />
</HeaderBox>
</Header>
<Outlet>
<Small style={{ paddingBottom: '0' }}>1 instance paused</Small>
<Small style={{ paddingBottom: '0' }}>1 instances stopped</Small>
<Small style={{ paddingBottom: '0' }}>1 instance not responding</Small>
</Outlet>
</Card>;
```
#### Card > Provisioning
```jsx
const React = require('react');
const { Card, Header, HeaderBox, HeaderMeta, Outlet } = require('.');
const { Row, Col } = require('react-styled-flexboxgrid');
const { H4, P } = require('../text');
const { default: StatusLoader } = require('../status-loader');
const {
IconActions,
IconActionsLight,
InstancesIconLight,
HealthyIcon
} = require('../icons');
[
<Row>
<Col xs={12}>
<Card collapsed disabled>
<Header>
<HeaderMeta>
<Row middle="xs">
<Col xs={2} sm={1} md={1}>
<H4>Nginx</H4>
</Col>
<Col xs={8} sm={4} md={2}>
<StatusLoader marginLeft="0" inline row msg="Provisioning" />
</Col>
</Row>
</HeaderMeta>
<HeaderBox border="left" actionable>
<IconActions />
</HeaderBox>
</Header>
</Card>
</Col>
</Row>,
<br />,
<Row>
<Col xs={12}>
<Card shadow>
<Header>
<HeaderMeta>
<Row between="xs" middle="xs">
<Col xs={4} sm={9} md={10}>
<H4>Nginx</H4>
</Col>
<Col xs={8} sm={3} md={2}>
<P>
<InstancesIconLight marginRight="0.5" /> 4 of 4 instances
</P>
</Col>
</Row>
</HeaderMeta>
<HeaderBox border="left" actionable>
<IconActionsLight />
</HeaderBox>
</Header>
<Outlet>
<div
style={{
display: 'flex',
flex: '1 0 auto',
flexDirection: 'column',
alignSelf: 'stretch',
justifyContent: 'space-between',
alignContent: 'stretch',
alignItems: 'stretch'
}}
>
<div style={{ flex: '0 1 auto', alignSelf: 'flex-start' }}>
<StatusLoader
marginLeft="0"
inline
row
msg="Provisioning 3 instances"
/>
</div>
<P style={{ flex: '0 1 auto', alignSelf: 'stretch' }}>
<HealthyIcon width="18" /> Healthy
</P>
</div>
</Outlet>
</Card>
</Col>
</Row>
];
```
#### Card > Disabled
```jsx
const React = require('react');
const { Card, Header, HeaderBox, HeaderMeta, Outlet } = require('.');
const { Row, Col } = require('react-styled-flexboxgrid');
const { H4, P } = require('../text');
const { IconActions } = require('../icons');
<Card disabled shadow>
<Header>
<HeaderMeta>
<Row between="xs" middle="xs">
<Col xs={2} sm={9} md={10}>
<H4>Nginx</H4>
</Col>
<Col xs={5} sm={2} md={1}>
<P>1 Instance</P>
</Col>
</Row>
</HeaderMeta>
<HeaderBox border="left" actionable>
<IconActions />
</HeaderBox>
</Header>
<Outlet />
</Card>;
```
#### Card > Instance
```jsx
const React = require('react');
const { Card, Outlet } = require('.');
const { H4, P } = require('../text');
const { HealthyIcon } = require('../icons');
<Card>
<Outlet>
<div
style={{
display: 'flex',
flex: '1 0 auto',
flexDirection: 'column',
alignSelf: 'stretch',
justifyContent: 'space-between',
alignContent: 'stretch',
alignItems: 'stretch'
}}
>
<div style={{ flex: '0 1 auto', alignSelf: 'flex-start' }}>
<H4>percona_primary</H4>
</div>
<P style={{ flex: '0 1 auto', alignSelf: 'stretch' }}>
<HealthyIcon width="18" /> Healthy
</P>
</div>
</Outlet>
</Card>;
```
#### Card > Instance > Stacked
```jsx
const React = require('react');
const { Card, Outlet } = require('.');
const { H4, P } = require('../text');
const { HealthyIcon } = require('../icons');
<Card stacked shadow>
<Outlet>
<div
style={{
display: 'flex',
flex: '1 0 auto',
flexDirection: 'column',
alignSelf: 'stretch',
justifyContent: 'space-between',
alignContent: 'stretch',
alignItems: 'stretch'
}}
>
<div style={{ flex: '0 1 auto', alignSelf: 'flex-start' }}>
<H4>percona_primary</H4>
</div>
<P style={{ flex: '0 1 auto', alignSelf: 'stretch' }}>
<HealthyIcon width="18" /> Healthy
</P>
</div>
</Outlet>
</Card>;
```
#### Card > Instance > Group
```jsx
const React = require('react');
const { Card, Outlet } = require('.');
const { H4, P } = require('../text');
const { HealthyIcon } = require('../icons');
[
<Card marginBottom="6px">
<Outlet>
<div
style={{
display: 'flex',
flex: '1 0 auto',
flexDirection: 'column',
alignSelf: 'stretch',
justifyContent: 'space-between',
alignContent: 'stretch',
alignItems: 'stretch'
}}
>
<div style={{ flex: '0 1 auto', alignSelf: 'flex-start' }}>
<H4>percona_secondary</H4>
</div>
<P style={{ flex: '0 1 auto', alignSelf: 'stretch' }}>
<HealthyIcon width="18" /> Healthy
</P>
</div>
</Outlet>
</Card>,
<Card marginBottom="6px">
<Outlet>
<div
style={{
display: 'flex',
flex: '1 0 auto',
flexDirection: 'column',
alignSelf: 'stretch',
justifyContent: 'space-between',
alignContent: 'stretch',
alignItems: 'stretch'
}}
>
<div style={{ flex: '0 1 auto', alignSelf: 'flex-start' }}>
<H4>percona_secondary</H4>
</div>
<P style={{ flex: '0 1 auto', alignSelf: 'stretch' }}>
<HealthyIcon width="18" /> Healthy
</P>
</div>
</Outlet>
</Card>,
<Card shadow stacked>
<Outlet>
<div
style={{
display: 'flex',
flex: '1 0 auto',
flexDirection: 'column',
alignSelf: 'stretch',
justifyContent: 'space-between',
alignContent: 'stretch',
alignItems: 'stretch'
}}
>
<div style={{ flex: '0 1 auto', alignSelf: 'flex-start' }}>
<H4>percona_secondary</H4>
</div>
<P style={{ flex: '0 1 auto', alignSelf: 'stretch' }}>
<HealthyIcon width="18" /> Healthy
</P>
</div>
</Outlet>
</Card>
];
```
#### Card > Instance > List
```jsx
const React = require('react');
const { Card, Header, HeaderBox, HeaderMeta } = require('.');
const { Row, Col } = require('react-styled-flexboxgrid');
const { H4, P } = require('../text');
const { HealthyIcon, IconActions, DataCenterIcon } = require('../icons');
[
<Card collapsed>
<Header transparent>
<HeaderMeta>
<Row between="xs" middle="xs">
<Col xs={2} sm={9} md={10}>
<H4>Nginx</H4>
</Col>
<Col xs={5} sm={2} md={1}>
<P>
<HealthyIcon /> Healthy
</P>
</Col>
<Col xs={5} sm={2} md={1}>
<P>
<DataCenterIcon /> eu-ams-1
</P>
</Col>
</Row>
</HeaderMeta>
<HeaderBox border="left" actionable>
<IconActions />
</HeaderBox>
</Header>
</Card>
];
```

View File

@ -1,67 +0,0 @@
import { Subscriber } from 'joy-react-broadcast';
import Baseline from '../baseline';
import typography from '../typography';
import is, { isNot } from 'styled-is';
import remcalc from 'remcalc';
import styled from 'styled-components';
import PropTypes from 'prop-types';
import Title from './title';
import React from 'react';
const StyledTitle = Title.extend`
${typography.normal};
flex-grow: 1;
flex-basis: ${remcalc(90)};
${isNot('collapsed')`
padding-bottom: ${remcalc(12)};
`};
${is('disabled')`
color: ${props => props.theme.text};
`};
`;
const InnerDescription = styled.div`
justify-content: flex-start;
display: flex;
align-items: center;
height: 100%;
position: relative;
span {
display: flex;
flex-direction: column;
height: 100%;
align-items: flex-start;
justify-content: space-between;
}
`;
const Description = ({ children, ...rest }) => {
const render = ({ collapsed = false }) => (
<StyledTitle
collapsed={collapsed}
name="card-description"
xs={collapsed ? 6 : 12}
{...rest}
>
<InnerDescription collapsed={collapsed}>
<span>{children}</span>
</InnerDescription>
</StyledTitle>
);
return <Subscriber channel="card">{render}</Subscriber>;
};
Description.propTypes = {
children: PropTypes.node,
/**
* @ignore
*/
collapsed: PropTypes.bool
};
export default Baseline(Description);

View File

@ -1,49 +0,0 @@
import { Subscriber } from 'joy-react-broadcast';
import is from 'styled-is';
import styled from 'styled-components';
import Baseline from '../baseline';
import typography from '../typography';
import theme from '../theme';
import remcalc from 'remcalc';
import PropTypes from 'prop-types';
import Title from './title';
import React from 'react';
const StyledTitle = Title.extend`
${typography.normal};
flex-grow: 1;
flex-basis: ${remcalc(90)};
`;
const Span = styled.span`
display: inline-block;
flex-direction: column;
${typography.normal};
font-size: ${remcalc(13)};
font-weight: 500;
text-transform: uppercase;
color: ${theme.greyTransparent};
transition: all 300ms ease;
${is('selected')`
color: rgba(41, 49, 194, 0.5);
`};
`;
const Footer = ({ children, selected }) => {
const render = () => (
<StyledTitle name="card-footer">
<Span selected={selected}>{children}</Span>
</StyledTitle>
);
return <Subscriber channel="card">{render}</Subscriber>;
};
Footer.propTypes = {
children: PropTypes.node
};
export default Baseline(Footer);

View File

@ -1,16 +0,0 @@
import remcalc from 'remcalc';
import Baseline from '../baseline';
import View from './view';
import React from 'react';
const StyledView = View.extend`
display: block;
padding: ${remcalc(12, 24, 6, 24)};
background-color: ${props => props.grey};
`;
const GroupView = ({ children, ...rest }) => (
<StyledView {...rest}>{children}</StyledView>
);
export default Baseline(GroupView);

View File

@ -1,24 +1,39 @@
import React from 'react';
import { Broadcast, Subscriber } from 'joy-react-broadcast';
import remcalc from 'remcalc';
import PropTypes from 'prop-types';
import is from 'styled-is';
import Baseline from '../baseline';
import Card from './card';
import is, { isNot, isOr } from 'styled-is';
import remcalc from 'remcalc';
const StyledCard = Card.extend`
import Baseline from '../baseline';
import Card, { BaseCard } from './card';
const BaseHeader = BaseCard.extend`
flex-direction: row;
background-color: ${props => props.theme.primary};
border: solid ${remcalc(1)} ${props => props.theme.primary};
box-shadow: none;
width: calc(100% + ${remcalc(2)});
margin: ${remcalc(-1)} ${remcalc(-1)} 0 ${remcalc(-1)};
${is('parentCollapsed')`
margin: ${remcalc(-1)};
box-shadow: none;
`};
${isOr('tertiary', 'transparent')`
box-shadow: none;
background-color: transparent;
border-width: 0;
margin: 0;
`};
${isNot('secondary', 'tertiary')`
${is('transparent')`
color: ${props => props.theme.text};
`};
`};
${is('disabled')`
background-color: ${props => props.theme.disabled};
color: ${props => props.theme.text};
border-color: ${props => props.theme.grey};
box-shadow: none;
`};
button {
@ -27,26 +42,143 @@ const StyledCard = Card.extend`
}
`;
const Header = ({ children, ...rest }) => {
const render = value => {
const { active } = value;
const BaseBox = BaseCard.extend`
width: ${remcalc(49)};
min-width: ${remcalc(49)};
height: ${remcalc(46)};
display: flex;
flex: 0 0 ${remcalc(49)};
flex-direction: column;
justify-content: center;
align-items: center;
transition: background-color 0ms ease;
background-color: transparent;
border-width: 0;
border-radius: 0;
box-shadow: none;
${is('border')`
border-right-width: ${props => (props.border === 'right' ? remcalc(1) : 0)};
border-left-width: ${props => (props.border === 'left' ? remcalc(1) : 0)};
`};
${is('actionable', 'secondary')`
&:hover {
background-color: ${props => props.theme.primaryHover};
}
`};
${is('disabled')`
color: ${props => props.theme.text};
border-color: ${props => props.theme.grey};
box-shadow: none;
&:hover {
background-color: transparent;
}
`};
`;
const BaseMeta = BaseCard.extend`
height: ${remcalc(47)};
width: auto;
min-width: auto;
padding: 0 ${remcalc(12)};
display: flex;
flex: 1 0 auto;
flex-direction: column;
justify-content: center;
align-items: stretch;
align-conent: stretch;
background-color: transparent;
border-width: 0;
box-shadow: none;
`;
export const Box = ({ children, border, actionable, ...rest }) => {
const render = ({ secondary, transparent, parentCollapsed, ...value }) => {
// if parent is collapsed, show border
// if parent is not collapsed, only if this is secondary and not transparent
const showBorder = parentCollapsed || (secondary && !transparent);
const newBorder = showBorder && border;
return (
<BaseBox
{...rest}
{...value}
name="card-header-box"
border={newBorder}
secondary={secondary}
transparent={transparent}
parentCollapsed={parentCollapsed}
actionable={actionable}
collapsed
>
{children}
</BaseBox>
);
};
return <Subscriber channel="card">{render}</Subscriber>;
};
Box.propTypes = {
...Card.propTypes,
children: PropTypes.node,
border: PropTypes.oneOf(['left', 'right'])
};
Box.defaultProps = {
...Card.defaultProps,
children: null,
border: null
};
export const Meta = ({ children, ...rest }) => (
<Subscriber channel="card">
{value => (
<BaseMeta {...rest} {...value} name="card-header-meta" collapsed>
{children}
</BaseMeta>
)}
</Subscriber>
);
const Header = ({ children, transparent, shadow, ...rest }) => {
const render = ({ secondary, tertiary, collapsed, ...value }) => {
const parentPrimary = !secondary && !tertiary;
// if transparent and parent is secondary, keep seconday
// if parent is secondary, keep being secondary or
// if parent is primary, become secondary
const isSecondary = transparent ? secondary : secondary || parentPrimary;
// if parent is primary, don't become transparent
const isTransparent = transparent || secondary || tertiary;
const newValue = {
...value,
fromHeader: true
parentCollapsed: collapsed,
secondary: isSecondary,
tertiary,
transparent: isTransparent,
collapsed: true,
shadow: Boolean(shadow)
};
return (
<Broadcast channel="card" value={newValue}>
<StyledCard
name="card-header"
active={active}
collapsed
headed
<BaseHeader
{...rest}
{...newValue}
name="card-header"
parentCollapsed={collapsed}
shadow={shadow}
>
{children}
</StyledCard>
</BaseHeader>
</Broadcast>
);
};
@ -58,4 +190,8 @@ Header.propTypes = {
children: PropTypes.node
};
Header.defaultProps = {
children: null
};
export default Baseline(Header);

View File

@ -1,19 +1,8 @@
export { default as CardDescription } from './description.js';
export { default as CardHeader } from './header.js';
export { default as CardGroupView } from './group-view.js';
export { default as Card } from './card.js';
export { default as CardMeta } from './meta.js';
export { default as CardOptions } from './options.js';
export { default as CardOutlet } from './outlet.js';
export { default as CardSubTitle } from './subtitle.js';
export { default as CardTitle } from './title.js';
export { default as CardAction } from './action.js';
export { default as CardView } from './view.js';
export { default as CardFooter } from './footer.js';
export { default as CardLabel } from './label.js';
export { default as Card } from './card';
export { default as Outlet } from './outlet';
export {
default as CardInfo,
Label as CardInfoLabel,
IconContainer as CardInfoIconContainer
} from './info.js';
default as Header,
Meta as HeaderMeta,
Box as HeaderBox
} from './header';

View File

@ -1,57 +0,0 @@
import PropTypes from 'prop-types';
import styled from 'styled-components';
import remcalc from 'remcalc';
import is from 'styled-is';
import BaseLabel from '../label';
export const Label = BaseLabel.extend`
display: inline-block;
margin-left: 0;
${is('light')`
color: ${props => props.theme.white};
`};
${is('disabled')`
color: ${props => props.theme.text};
`};
${is('left')`
margin-left: ${remcalc(12)};
`};
`;
Label.propTypes = {
light: PropTypes.bool,
disabled: PropTypes.bool,
left: PropTypes.bool
};
export const IconContainer = styled.div`
display: flex;
> svg {
${is('light')`
fill: ${props => props.theme.white};
`};
${is('disabled')`
fill: ${props => props.theme.text};
`};
}
`;
IconContainer.propTypes = {
light: PropTypes.bool,
disabled: PropTypes.bool
};
export default styled.div`
height: 100%;
float: right;
display: flex;
align-items: center;
justify-content: flex-end;
flex-direction: row;
`;

View File

@ -1,73 +0,0 @@
import React from 'react';
import remcalc from 'remcalc';
import styled from 'styled-components';
import is, { isNot } from 'styled-is';
const Dot = styled.span`
width: ${remcalc(6)};
height: ${remcalc(6)};
border-radius: ${remcalc(3)};
${is('hasChildren')`
margin-left: ${remcalc(6)};
`};
background-color: ${props => props.theme[props.color]};
align-self: auto;
flex: none;
`;
const Icon = styled.span`
/* trick prettier */
background-color: none;
`;
const Label = styled.label`
line-height: 1;
padding: 0 ${remcalc(18)};
display: flex;
flex-direction: row;
flex: none;
align-items: center;
justify-content: center;
min-width: ${remcalc(100)};
padding-left: 0;
${isNot('hasDot')`
min-width: ${remcalc(88)};
`};
${isNot('hasChildren')`
width: ${remcalc(6)};
min-width: ${remcalc(6)};
`};
`;
const Span = styled.span`
align-self: auto;
flex: 1 1 auto;
${is('hasDot')`
text-align: right;
`};
`;
export default ({ color, icon, children, width, ...rest }) => {
const hasIcon = Boolean(icon);
const hasDot = hasIcon || Boolean(color);
const hasChildren = Array.isArray(children)
? children.length
: Boolean(children);
return (
<Label {...rest} hasDot={hasDot} hasChildren={hasChildren}>
{children && <Span hasDot={hasDot}>{children}</Span>}
{icon && <Icon>{icon}</Icon>}
{color && <Dot color={color} hasChildren={hasChildren} />}
</Label>
);
};

View File

@ -1,61 +0,0 @@
import { Row, Col } from 'react-styled-flexboxgrid';
import { Subscriber } from 'joy-react-broadcast';
import Baseline from '../baseline';
import is from 'styled-is';
import PropTypes from 'prop-types';
import View from './view';
import React from 'react';
const InnerRow = Row.extend`
display: block;
height: 100%;
position: absolute;
top: 50%;
transform: translateY(-50%);
${is('collapsed')`
width: 100%;
display: flex;
`};
`;
const Meta = ({ children, ...rest }) => {
const render = ({
collapsed = false,
fromHeader = false,
headed = false
}) => {
const meta = (
<Col
name="card-meta"
xs={collapsed ? 12 : 6}
collapsed={collapsed}
fromHeader={fromHeader}
headed={headed}
{...rest}
>
<InnerRow collapsed={collapsed}>{children}</InnerRow>
</Col>
);
return fromHeader ? (
<View collapsed fromHeader>
{meta}
</View>
) : (
meta
);
};
return <Subscriber channel="card">{render}</Subscriber>;
};
Meta.propTypes = {
children: PropTypes.node,
collapsed: PropTypes.bool,
fromHeader: PropTypes.bool,
headed: PropTypes.bool
};
export default Baseline(Meta);

View File

@ -1,222 +0,0 @@
[
{
"instance": "2c921f3a-8bc3-4f57-9cd7-789ebae72061",
"name": "AVG_MEM_BYTES",
"start": "2017-10-05T13:12:13Z",
"end": "2017-10-05T13:13:58Z",
"metrics": [
{
"time": "2017-10-05T13:12:28Z",
"value": 97595392,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:12:43Z",
"value": 94142464,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:12:58Z",
"value": 63918080,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:13:13Z",
"value": 94023680,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:13:28Z",
"value": 99467264,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:13:43Z",
"value": 99737600,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:13:58Z",
"value": 86839296,
"__typename": "Metric"
}
],
"__typename": "InstanceMetric"
},
{
"instance": "68d3046e-8e34-4f5d-a0e5-db3795a250fd",
"name": "AVG_MEM_BYTES",
"start": "2017-10-05T13:12:13Z",
"end": "2017-10-05T13:13:58Z",
"metrics": [
{
"time": "2017-10-05T13:12:28Z",
"value": 99844096,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:12:43Z",
"value": 93655040,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:12:58Z",
"value": 64172032,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:13:13Z",
"value": 100237312,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:13:28Z",
"value": 99844096,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:13:43Z",
"value": 88035328,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:13:58Z",
"value": 100237312,
"__typename": "Metric"
}
],
"__typename": "InstanceMetric"
},
{
"instance": "2ea99763-3b44-4179-8393-d66d94961051",
"name": "AVG_MEM_BYTES",
"start": "2017-10-05T13:12:13Z",
"end": "2017-10-05T13:13:58Z",
"metrics": [
{
"time": "2017-10-05T13:12:28Z",
"value": 98512896,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:12:43Z",
"value": 98258944,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:12:58Z",
"value": 91385856,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:13:13Z",
"value": 50900992,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:13:28Z",
"value": 98512896,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:13:43Z",
"value": 98033664,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:13:58Z",
"value": 80048128,
"__typename": "Metric"
}
],
"__typename": "InstanceMetric"
},
{
"instance": "25f6bc62-63b8-4959-908e-1f6d7ff6341d",
"name": "AVG_MEM_BYTES",
"start": "2017-10-05T13:12:13Z",
"end": "2017-10-05T13:13:58Z",
"metrics": [
{
"time": "2017-10-05T13:12:28Z",
"value": 95563776,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:12:43Z",
"value": 48996352,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:12:58Z",
"value": 89772032,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:13:13Z",
"value": 83755008,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:13:28Z",
"value": 101920768,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:13:43Z",
"value": 95576064,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:13:58Z",
"value": 101699584,
"__typename": "Metric"
}
],
"__typename": "InstanceMetric"
},
{
"instance": "8be01042-0281-4a77-a357-25979e87bf3d",
"name": "AVG_MEM_BYTES",
"start": "2017-10-05T13:12:13Z",
"end": "2017-10-05T13:13:58Z",
"metrics": [
{
"time": "2017-10-05T13:12:28Z",
"value": 101732352,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:12:43Z",
"value": 101732352,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:12:58Z",
"value": 94240768,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:13:13Z",
"value": 102371328,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:13:28Z",
"value": 61218816,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:13:43Z",
"value": 102371328,
"__typename": "Metric"
},
{
"time": "2017-10-05T13:13:58Z",
"value": 100716544,
"__typename": "Metric"
}
],
"__typename": "InstanceMetric"
}
]

View File

@ -1,129 +0,0 @@
import { Subscriber } from 'joy-react-broadcast';
import styled from 'styled-components';
import { Nav } from 'normalized-styled-components';
import Baseline from '../baseline';
import remcalc from 'remcalc';
import is, { isOr, isNot } from 'styled-is';
import PropTypes from 'prop-types';
import Button from '../button';
import React from 'react';
const StyledNav = Nav.extend`
flex: 0 0 ${remcalc(47)};
border-left: ${remcalc(1)} solid ${props => props.theme.grey};
box-sizing: border-box;
button {
margin-bottom: 0;
margin-top: 0;
}
${is('fromHeader') &&
isNot('disabled')`
border-left-color: ${props => props.theme.primary};
`};
${isOr('disabled', 'active')`
border-left-color: ${props => props.theme.grey};
`};
`;
const StyledButton = Button.extend`
position: relative;
border-width: 0;
box-shadow: none;
width: 100%;
min-width: ${remcalc(46)} !important;
height: ${remcalc(124)};
display: flex;
justify-content: center;
align-items: center;
overflow-x: visible;
overflow-y: visible;
${is('collapsed')`
height: ${remcalc(46)};
`};
&:focus {
border-width: 0;
}
&:hover {
border-width: 0;
}
&:active,
&:active:hover,
&:active:focus {
border-width: 0;
}
${is('disabled')`
background-color: ${props => props.theme.disabled};
border-color: ${props => props.theme.grey};
&:focus,
&:hover,
&:active,
&:active:hover,
&:active:focus {
background-color: ${props => props.theme.grey};
}
`};
`;
const StyledContainer = styled.div`
position: absolute;
left: 50%;
top: 35%; /* I don't know why this doesn't center with 50% */
`;
const StyledCircle = styled.div`
margin: 0 0 ${remcalc(2)} ${remcalc(-2)};
border-radius: 50%;
background-color: ${props => props.theme.white};
width: ${remcalc(4)};
height: ${remcalc(4)};
${is('secondary')`
background-color: ${props => props.theme.secondary};
`};
${is('disabled')`
background-color: ${props => props.theme.text};
`};
`;
const Options = ({ children, ...rest }) => {
const render = ({ fromHeader = false, collapsed = false, active = true }) => (
<StyledNav active={active} fromHeader={fromHeader} name="card-options">
<StyledButton
secondary={!fromHeader}
collapsed={collapsed}
active={active}
rect
{...rest}
>
<StyledContainer>
<StyledCircle {...rest} active={active} secondary={!fromHeader} />
<StyledCircle {...rest} active={active} secondary={!fromHeader} />
<StyledCircle {...rest} active={active} secondary={!fromHeader} />
</StyledContainer>
</StyledButton>
</StyledNav>
);
return <Subscriber channel="card">{render}</Subscriber>;
};
Options.propTypes = {
collapsed: PropTypes.bool,
fromHeader: PropTypes.bool
};
export default Baseline(Options);

View File

@ -1,48 +1,59 @@
import { Subscriber } from 'joy-react-broadcast';
import typography from '../typography';
import Baseline from '../baseline';
import { Col } from 'react-styled-flexboxgrid';
import is, { isNot } from 'styled-is';
import remcalc from 'remcalc';
import PropTypes from 'prop-types';
import React from 'react';
import { Subscriber } from 'joy-react-broadcast';
import PropTypes from 'prop-types';
import remcalc from 'remcalc';
import is from 'styled-is';
const StyledCol = Col.extend`
${typography.normal};
import Baseline from '../baseline';
import Card, { BaseCard } from './card';
display: block;
min-width: auto;
max-width: ${remcalc(480)};
margin-left: auto;
const BaseOutlet = BaseCard.extend`
box-sizing: border-box;
flex: 1 1 auto;
flex-direction: column;
border-width: 0;
padding: ${remcalc(13)};
background-color: transparent;
${is('collapsed')`
display: none;
`};
${isNot('active')`
color: ${props => props.theme.grey};
`};
& > [name='card']:not(:last-child) {
margin-bottom: ${remcalc(13)};
}
& > [name='card']:last-child {
margin-bottom: ${remcalc(7)};
}
`;
const Outlet = ({ children, ...rest }) => {
const render = ({ active = true, collapsed = false }) => (
<StyledCol
name="card-outlet"
active={active}
collapsed={collapsed}
xs={6}
{...rest}
>
{children}
</StyledCol>
);
return <Subscriber channel="card">{render}</Subscriber>;
};
export const Outlet = ({ children, ...rest }) => (
<Subscriber channel="card">
{({ secondary, tertiary, collapsed }) => (
<BaseOutlet
{...rest}
name="card-outlet"
secondary={secondary}
tertiary={tertiary}
collapsed={collapsed}
>
{children}
</BaseOutlet>
)}
</Subscriber>
);
Outlet.propTypes = {
children: PropTypes.node,
collapsed: PropTypes.bool
...Card.propTypes,
children: PropTypes.node
};
Outlet.defaultProps = {
...Card.defaultProps,
children: null
};
export default Baseline(Outlet);

View File

@ -1,11 +0,0 @@
import { css } from 'styled-components';
import remcalc from 'remcalc';
export default css`
margin-bottom: ${remcalc(16)};
box-shadow: 0 ${remcalc(8)} 0 ${remcalc(-5)}
${props => props.theme.background},
0 ${remcalc(8)} ${remcalc(1)} ${remcalc(-4)} ${props => props.theme.grey},
0 ${remcalc(16)} 0 ${remcalc(-10)} ${props => props.theme.background},
0 ${remcalc(16)} ${remcalc(1)} ${remcalc(-9)} ${props => props.theme.grey};
`;

View File

@ -1,71 +0,0 @@
import { Subscriber } from 'joy-react-broadcast';
import styled from 'styled-components';
import Baseline from '../baseline';
import typography from '../typography';
import remcalc from 'remcalc';
import is from 'styled-is';
import PropTypes from 'prop-types';
import Title from './title';
import React from 'react';
const Span = styled.span`
display: inline-block;
flex-direction: column;
${typography.normal};
font-style: normal;
font-stretch: normal;
font-size: ${remcalc(14)};
justify-content: flex-end;
${is('collapsed')`
display: flex;
`};
${is('disabled')`
color: ${props => props.theme.text};
`};
${is('fromHeader')`
color: ${props => props.theme.white};
`};
`;
const StyledTitle = Title.extend`
display: inline-block;
padding: 0 ${remcalc(18)};
${typography.normal};
${is('collapsed')`
display: flex;
padding: 0;
`};
`;
const Subtitle = ({ children, ...props }) => {
const render = ({ active = true, fromHeader = false, collapsed = false }) => (
<StyledTitle
name="card-subtitle"
fromHeader={fromHeader}
collapsed={collapsed}
active={active}
{...props}
>
<Span fromHeader={fromHeader} collapsed={collapsed}>
{children}
</Span>
</StyledTitle>
);
return <Subscriber channel="card">{render}</Subscriber>;
};
Subtitle.propTypes = {
children: PropTypes.node,
collapsed: PropTypes.bool,
fromHeader: PropTypes.bool
};
export default Baseline(Subtitle);

File diff suppressed because it is too large Load Diff

View File

@ -1,122 +0,0 @@
import { Subscriber } from 'joy-react-broadcast';
import isString from 'lodash.isstring';
import { Link as BaseLink } from 'react-router-dom';
import remcalc from 'remcalc';
import is from 'styled-is';
import styled from 'styled-components';
import PropTypes from 'prop-types';
import React from 'react';
import typography from '../typography';
import Baseline from '../baseline';
const Container = styled.div`
font-size: ${remcalc(15)};
line-height: 1.5;
color: ${props => props.theme.secondary};
${typography.semibold};
display: flex;
flex-direction: row;
align-items: center;
flex-grow: 4;
flex-basis: ${remcalc(90)};
width: 100%;
padding: ${remcalc(12)} ${remcalc(18)} 0 ${remcalc(18)};
transition: all 300ms ease;
${is('fromHeader')`
color: ${props => props.theme.white};
`};
${is('collapsed')`
width: auto;
padding: 0 ${remcalc(18)};
`};
${is('disabled')`
color: ${props => props.theme.text};
`};
${is('selected')`
color: ${props => props.theme.primary};
`};
`;
const Span = styled.span`
display: inline-block;
flex-direction: column;
justify-content: center;
${is('collapsed')`
display: flex;
`};
${is('link')`
text-decoration-color: ${props => props.theme.secondary};
text-decoration-line: underline;
text-decoration-style: solid;
`};
`;
const Link = styled(BaseLink)`
color: ${props => props.theme.secondary};
${is('fromHeader')`
color: ${props => props.theme.white};
`};
${is('selected')`
color: ${props => props.theme.primary};
`};
`;
const Title = ({ children, to, selected, ...rest }) => {
const render = ({ collapsed = false, active = true, fromHeader = false }) => {
const _children = isString(children) ? (
<Span link={Boolean(to)}>{children}</Span>
) : (
children
);
const __children = to ? (
<Link to={to} selected={selected} fromHeader={fromHeader}>
{_children}
</Link>
) : (
_children
);
return (
<Container
collapsed={collapsed}
fromHeader={fromHeader}
active={active}
name="card-title"
xs={collapsed ? 6 : 12}
{...rest}
>
{__children}
</Container>
);
};
return <Subscriber channel="card">{render}</Subscriber>;
};
Title.propTypes = {
children: PropTypes.node,
/**
* @ignore
*/
collapsed: PropTypes.bool,
/**
* @ignore
*/
fromHeader: PropTypes.bool
};
export default Baseline(Title);

View File

@ -1,56 +0,0 @@
import { Subscriber } from 'joy-react-broadcast';
import Baseline from '../baseline';
import remcalc from 'remcalc';
import is from 'styled-is';
import { Row } from 'react-styled-flexboxgrid';
import PropTypes from 'prop-types';
import React from 'react';
const StyledView = Row.extend`
flex: 1;
margin: 0;
height: auto;
padding-top: 0;
min-width: auto;
flex-direction: row;
/*${is('headed')`
padding-top: ${remcalc(47)};
`};
${is('collapsed')`
height: ${remcalc(47)};
`};
${is('fromHeader')`
padding-top: 0;
`};*/
`;
const View = ({ children, ...rest }) => {
const render = value => {
const newValue = {
...value,
...rest
};
const hide = newValue.headed && !newValue.fromHeader && newValue.collapsed;
return hide ? null : (
<StyledView name="card-view" {...newValue}>
{children}
</StyledView>
);
};
return <Subscriber channel="card">{render}</Subscriber>;
};
View.propTypes = {
children: PropTypes.node,
collapsed: PropTypes.bool,
fromHeader: PropTypes.bool,
headed: PropTypes.bool
};
export default Baseline(View);

View File

@ -1,6 +1,7 @@
```
const FormGroup = require('./group').default;
const Label = require('./label').default;
const React = require('react');
const { default: FormGroup } = require('./group');
const { default: Label } = require('./label');
<FormGroup name="test">
<Checkbox checked>
@ -21,9 +22,10 @@ const Label = require('./label').default;
#### Checkbox input validation
```
const FormMeta = require('./meta').default;
const FormGroup = require('./group').default;
const Label = require('./label').default;
const React = require('react');
const { default: FormMeta } = require('./meta');
const { default: FormGroup } = require('./group');
const { default: Label } = require('./label');
<div>
<FormGroup>

View File

@ -1,8 +1,10 @@
#### Input > Email
```jsx
const FormGroup = require('./group').default;
const Label = require('./label').default;
const React = require('react');
const { default: FormGroup } = require('./group');
const { default: Label } = require('./label');
const { default: Input } = require('./input');
<FormGroup>
<Label>Username</Label>
@ -13,8 +15,10 @@ const Label = require('./label').default;
#### Input > Disabled
```jsx
const FormGroup = require('./group').default;
const Label = require('./label').default;
const React = require('react');
const { default: FormGroup } = require('./group');
const { default: Label } = require('./label');
const { default: Input } = require('./input');
<FormGroup>
<Label disabled>Username</Label>
@ -25,9 +29,11 @@ const Label = require('./label').default;
#### Input > Error
```jsx
const FormGroup = require('./group').default;
const Label = require('./label').default;
const FormMeta = require('./meta').default;
const React = require('react');
const { default: FormGroup } = require('./group');
const { default: Label } = require('./label');
const { default: FormMeta } = require('./meta');
const { default: Input } = require('./input');
<FormGroup>
<Label>Email Address</Label>
@ -39,9 +45,11 @@ const FormMeta = require('./meta').default;
#### Input > Warning
```jsx
const FormGroup = require('./group').default;
const Label = require('./label').default;
const FormMeta = require('./meta').default;
const React = require('react');
const { default: FormGroup } = require('./group');
const { default: Label } = require('./label');
const { default: FormMeta } = require('./meta');
const { default: Input } = require('./input');
<FormGroup>
<Label>Email Address</Label>
@ -53,9 +61,11 @@ const FormMeta = require('./meta').default;
#### Input > Success
```jsx
const FormGroup = require('./group').default;
const Label = require('./label').default;
const FormMeta = require('./meta').default;
const React = require('react');
const { default: FormGroup } = require('./group');
const { default: Label } = require('./label');
const { default: FormMeta } = require('./meta');
const { default: Input } = require('./input');
<FormGroup>
<Label>Email Address</Label>

View File

@ -1,3 +1,5 @@
```
const React = require('react');
<NumberInput placeholder='I am the placeholder' value='1' onChange={() => {}} />
```

View File

@ -1,8 +1,9 @@
```jsx
const { RadioList } = require('./radio');
const FormGroup = require('./group').default;
const Label = require('./label').default;
const Legend = require('./legend').default;
const React = require('react');
const { default: Radio, RadioList } = require('./radio');
const { default: FormGroup } = require('./group');
const { default: Label } = require('./label');
const { default: Legend } = require('./legend');
<FormGroup name="who-killed">
<Legend>Who killed the radio star?</Legend>
@ -23,11 +24,12 @@ const Legend = require('./legend').default;
#### Radio input validation
```jsx
const { RadioList } = require('./radio');
const FormGroup = require('./group').default;
const Legend = require('./legend').default;
const FormMeta = require('./meta').default;
const Label = require('./label').default;
const React = require('react');
const { default: Radio, RadioList } = require('./radio');
const { default: FormGroup } = require('./group');
const { default: Legend } = require('./legend');
const { default: FormMeta } = require('./meta');
const { default: Label } = require('./label');
<div>
<FormGroup name="who-killed">

View File

@ -1,4 +1,7 @@
```jsx
const React = require('react');
const { default: Select } = require('./select');
<Select>
<option selected disabled>
Select a datacenter
@ -13,8 +16,10 @@
#### Select > Disabled
```jsx
const FormGroup = require('./group').default;
const Label = require('./label').default;
const React = require('react');
const { default: FormGroup } = require('./group');
const { default: Label } = require('./label');
const { default: Select } = require('./select');
<FormGroup>
<Label disabled>Your location</Label>
@ -33,9 +38,11 @@ const Label = require('./label').default;
#### Select > Warning
```jsx
const FormMeta = require('./meta').default;
const FormGroup = require('./group').default;
const Label = require('./label').default;
const React = require('react');
const { default: FormMeta } = require('./meta');
const { default: FormGroup } = require('./group');
const { default: Label } = require('./label');
const { default: Select } = require('./select');
<FormGroup>
<Label>Your location</Label>
@ -52,9 +59,11 @@ const Label = require('./label').default;
#### Select > Error
```jsx
const FormMeta = require('./meta').default;
const FormGroup = require('./group').default;
const Label = require('./label').default;
const React = require('react');
const { default: FormMeta } = require('./meta');
const { default: FormGroup } = require('./group');
const { default: Label } = require('./label');
const { default: Select } = require('./select');
<FormGroup>
<Label>Your location</Label>
@ -71,9 +80,11 @@ const Label = require('./label').default;
#### Select > Success
```jsx
const FormMeta = require('./meta').default;
const FormGroup = require('./group').default;
const Label = require('./label').default;
const React = require('react');
const { default: FormMeta } = require('./meta');
const { default: FormGroup } = require('./group');
const { default: Label } = require('./label');
const { default: Select } = require('./select');
<FormGroup>
<Label>Your location</Label>

View File

@ -1,7 +1,9 @@
```jsx
const React = require('react');
const { ToggleList } = require('./toggle');
const FormGroup = require('./group').default;
const Legend = require('./legend').default;
const { default: FormGroup } = require('./group');
const { default: Legend } = require('./legend');
const { default: Toggle } = require('./toggle');
<FormGroup name="who-killed-1">
<Legend>Who killed the radio star?</Legend>
@ -17,9 +19,11 @@ const Legend = require('./legend').default;
#### Toggle > Disabled
```jsx
const React = require('react');
const { ToggleList } = require('./toggle');
const FormGroup = require('./group').default;
const Legend = require('./legend').default;
const { default: FormGroup } = require('./group');
const { default: Legend } = require('./legend');
const { default: Toggle } = require('./toggle');
<FormGroup name="who-killed-2" disabled>
<Legend>Who killed the radio star?</Legend>

View File

@ -1,9 +1,7 @@
```
const HeaderBrand = require('./brand.js').default;
const HeaderItem = require('./item.js').default;
const HeaderNav = require('./nav.js').default;
const HeaderWrapper = require('./header-wrapper.js').default;
const { UserIconLight, DataCenterIconLight, TritonBetaIcon } = require('../icons');
const React = require('react');
const { default: HeaderBrand } = require('./brand.js');
const { default: HeaderItem } = require('./item.js');
<Header>
<HeaderWrapper>

View File

@ -1,3 +1,5 @@
```js noeditor
const React = require('react');
<Icons/>
```

View File

@ -31,7 +31,7 @@ export {
borderRadius,
bottomShadow,
bottomShadowDarker,
insetShaddow,
insetShadow,
tooltipShadow,
border
} from './boxes';
@ -124,3 +124,17 @@ export {
LoadingIcon,
ImportIcon
} from './icons';
export {
Container as TooltipContainer,
Target as TooltipTarget,
default as Tolltip
} from './tooltip';
export {
Container as PopoverContainer,
Target as PopoverTarget,
Item as PopoverItem,
Divider as PopoverDivider,
default as Popover
} from './popover';

View File

@ -3,7 +3,6 @@ import { withTheme, injectGlobal } from 'styled-components';
import FontFaceObserver from 'fontfaceobserver';
import { fontFaces } from '../typography/fonts';
import { loadedFontFamily } from '../typography';
import global from '../base/global';
const observers = Object.values(fontFaces).map(
@ -25,9 +24,13 @@ class RootContainer extends Component {
Promise.all(observers.map(obs => obs.load()))
.then(() => {
document.documentElement.className += ' fonts-loaded';
// eslint-disable-next-line
if (!document.documentElement.className.match(/fonts-loaded/)) {
document.documentElement.className += ' fonts-loaded';
}
})
.catch(err => {
// eslint-disable-next-line no-console
console.error(err);
});
}

View File

@ -1,7 +1,8 @@
#### Success/Educational
```jsx
const { Message, MessageTitle, MessageDescription } = require('./index.js');
const React = require('react');
const { Message, MessageTitle, MessageDescription } = require('.');
<Message>
<MessageTitle>Choosing deployment data center</MessageTitle>
@ -16,7 +17,8 @@ const { Message, MessageTitle, MessageDescription } = require('./index.js');
#### Error
```jsx
const { Message, MessageTitle, MessageDescription } = require('./index.js');
const React = require('react');
const { Message, MessageTitle, MessageDescription } = require('.');
<Message error>
<MessageTitle>Choosing deployment data center</MessageTitle>
@ -27,7 +29,8 @@ const { Message, MessageTitle, MessageDescription } = require('./index.js');
#### Warning
```jsx
const { Message, MessageTitle, MessageDescription } = require('./index.js');
const React = require('react');
const { Message, MessageTitle, MessageDescription } = require('.');
<Message warning>
<MessageTitle>Choosing deployment data center</MessageTitle>

View File

@ -1,3 +1,5 @@
```
const React = require('react');
<Modal />
```

View File

@ -1,4 +1,5 @@
```jsx
const React = require('react');
const { default: Popover, Container, Target, Item, Divider } = require('./');
const { Row, Col } = require('react-styled-flexboxgrid');

View File

@ -1,7 +1,8 @@
```
const Progressbar = require('./index').default;
const ProgressbarButton = require('./button').default;
const ProgressbarItem = require('./item').default;
const React = require('react');
const { default: Progressbar } = require('./index');
const { default: ProgressbarButton } = require('./button');
const { default: ProgressbarItem } = require('./item');
<Progressbar>
<ProgressbarItem>

View File

@ -1,7 +1,7 @@
import React from 'react';
import styled, { css } from 'styled-components';
import { A } from 'normalized-styled-components';
import { NavLink as RRNavLink, Link as RRLink } from 'react-router-dom';
import { NavLink as RRNavLink } from 'react-router-dom';
import remcalc from 'remcalc';
import is from 'styled-is';

View File

@ -1,12 +1,17 @@
### Double Range Slider
```
<Slider
minValue={0.25}
maxValue={8}
step={0.25}
value={{ min: 4, max: 4 }}
onChangeComplete={value => console.log(value)}
onChange={value => console.log(value)}
>vCPUs</Slider>
```jsx
const React = require('react');
const { default: Slider } = require('./slider');
<Slider
minValue={0.25}
maxValue={8}
step={0.25}
value={{ min: 4, max: 4 }}
onChangeComplete={value => console.log(value)}
onChange={value => console.log(value)}
>
vCPUs
</Slider>;
```

View File

@ -1,10 +1,11 @@
import React from 'react';
import styled from 'styled-components';
import is, { isNot } from 'styled-is';
import remcalc from 'remcalc';
import Widget from './widget';
import P from '../text/p';
import remcalc from 'remcalc';
import Baseline from '../baseline';
const Container = styled.div`
display: flex;
@ -20,7 +21,7 @@ const Container = styled.div`
`};
${is('row')`
flex-direction: row;
flex-direction: row;
`};
${is('row', 'inline')`
@ -41,9 +42,11 @@ const Msg = P.extend`
margin-left: ${remcalc(6)};
`;
export default ({ msg, row, inline, small }) => (
<Container row={row} inline={inline}>
const StatusLoader = ({ msg, row, inline, small, ...rest }) => (
<Container row={row} inline={inline} {...rest}>
<Loader />
{!small && <Msg>{msg || 'Loading...'}</Msg>}
</Container>
);
export default Baseline(StatusLoader);

View File

@ -1,5 +1,6 @@
```
const SectionLoader = require('./index').default
```jsx
const React = require('react');
const { default: SectionLoader } = require('./index');
<SectionLoader />
<SectionLoader />;
```

View File

@ -1,9 +1,8 @@
import React, { Component } from 'react';
import { ThemeProvider, injectGlobal } from 'styled-components';
import React from 'react';
import { ThemeProvider } from 'styled-components';
import theme from '../theme';
import Base from '../base';
import { loadedFontFamily } from '../typography';
import { RootContainer } from '../layout';
import 'codemirror/mode/jsx/jsx';

View File

@ -16,35 +16,45 @@ docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Heading_Elements
#### Heading 1
```jsx
const React = require('react');
const H1 = require('/').H1;
<H1>Inspire the lazy</H1>;
```
#### Heading 2
```jsx
const React = require('react');
const H2 = require('/').H2;
<H2>Inspire the lazy</H2>;
```
#### Heading 3
```jsx
const React = require('react');
const H3 = require('/').H3;
<H3>Inspire the lazy</H3>;
```
#### Heading 4
```jsx
const React = require('react');
const H4 = require('/').H4;
<H4>Inspire the lazy</H4>;
```
### Paragraph
```jsx
const React = require('react');
const P = require('/').P;
<P>
Joyent experts provide 360 degree support for modern application
architectures, including development frameworks, container orchestration
@ -59,7 +69,9 @@ or where space is more constrained, you can use the `<small>` element. This will
reduce the text size to 13px.
```jsx
const React = require('react');
const Small = require('/').Small;
<Small>
Triton is 100% open source and designed to eliminate cloud provider lock-in.
With support for popular container management tools like Kubernetes, augmented
@ -78,7 +90,9 @@ Read more about using the `<label>` element on the [MDN web
docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label).
```jsx
const React = require('react');
const Label = require('/').Label;
<Label>
Hybrid, Modern and Open, Triton is engineered to run the worlds largest cloud
native applications
@ -96,7 +110,9 @@ link](http://knowbody.github.io/react-router-docs/api/Link.html).
Primary anchor is a type of a link that sits outside the body text.
```
const React = require('react');
const Anchor = require('/').Anchor;
<Anchor href="https://joyent.com">Inspire the lazy</Anchor>
```
@ -106,7 +122,9 @@ Reversed anchors is used on dark backgrounds, where a default anchor would not
provide enough contrast.
```jsx
const React = require('react');
const Anchor = require('/').Anchor;
<span
style={{
'background-color': '#3B46CC',
@ -129,8 +147,9 @@ In-paragraph anchor is a link that sits inside a text components. The default
state does not have an underline. The underline appears on hover and click.
```jsx
const P = require('/').P;
const React = require('react');
const Anchor = require('/').Anchor;
<p>
Body text. Crack that whip. Give the past a slip. Step on a crack. Break your
momma's back. When a problem comes along.You must whip it.
@ -143,7 +162,9 @@ const Anchor = require('/').Anchor;
Disabled anchors cannot be actioned and the cursor is disabled.
```jsx
const React = require('react');
const Anchor = require('/').Anchor;
<Anchor disabled href="https://joyent.com">
Inspire the lazy disabled
</Anchor>;

View File

@ -1,5 +1,6 @@
```js noeditor
const Colors = require('./colors').default;
const React = require('react');
const { default: Colors } = require('./colors');
<Colors />
```

View File

@ -1,8 +1,6 @@
const webpackConfig = require('react-scripts/config/webpack.config.dev.js');
const webpackConfig = require('joyent-react-scripts/config/webpack.config.dev.js');
const { defaultHandlers } = require('react-docgen');
const dnHandler = require('react-docgen-displayname-handler');
const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const path = require('path');
module.exports = {
@ -13,38 +11,6 @@ module.exports = {
alias: Object.assign(webpackConfig.resolve.alias, {
'rsg-components/Wrapper': path.join(__dirname, 'src/styleguide/wrapper')
})
}),
module: Object.assign(webpackConfig.module, {
rules: [
{
test: /\.svg$/,
loader: 'svg-inline-loader'
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(js|jsx)$/,
use: ['babel-loader']
},
{
test: /\.(eot|ttf|woff|woff2)$/,
use: [
{
loader: 'file-loader'
}
]
},
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
loader: 'url-loader',
options: {
limit: 10000,
name: 'static/media/[name].[hash:8].[ext]'
}
}
]
})
}),
title: 'UI Toolkit',
@ -94,9 +60,9 @@ module.exports = {
{
name: 'Components',
components: () => [
'src/card/card.js',
'src/breadcrumb/index.js',
'src/button/index.js',
'src/card/card.js',
'src/form/checkbox.js',
'src/header/index.js',
'src/icons/icons.js',

View File

@ -38,124 +38,4 @@ describe('Visual Regressions', () => {
.goto('http://0.0.0.0:6060/#!/Card/4')
.then(() => chrome.screenshot())
.then(image => expect(image).toMatchImageSnapshot()));
// it('Card > Headed > Collapsed', () =>
// chrome
// .goto('http://0.0.0.0:6060/#!/Card/5')
// .then(() => chrome.screenshot())
// .then(image => expect(image).toMatchImageSnapshot()));
// it('Card > Headed', () =>
// chrome
// .goto('http://0.0.0.0:6060/#!/Card/6')
// .then(() => chrome.screenshot())
// .then(image => expect(image).toMatchImageSnapshot()));
// it('Card > Headed > Collapsed', () =>
// chrome
// .goto('http://0.0.0.0:6060/#!/Card/7')
// .then(() => chrome.screenshot())
// .then(image => expect(image).toMatchImageSnapshot()));
// it('Card > Headed', () =>
// chrome
// .goto('http://0.0.0.0:6060/#!/Card/8')
// .then(() => chrome.screenshot())
// .then(image => expect(image).toMatchImageSnapshot()));
// it('Card > Headed > Collapsed', () =>
// chrome
// .goto('http://0.0.0.0:6060/#!/Card/9')
// .then(() => chrome.screenshot())
// .then(image => expect(image).toMatchImageSnapshot()));
// it('Card > Headed', () =>
// chrome
// .goto('http://0.0.0.0:6060/#!/Card/10')
// .then(() => chrome.screenshot())
// .then(image => expect(image).toMatchImageSnapshot()));
// it('Card > Headed > Collapsed', () =>
// chrome
// .goto('http://0.0.0.0:6060/#!/Card/11')
// .then(() => chrome.screenshot())
// .then(image => expect(image).toMatchImageSnapshot()));
// it('Card > Headed', () =>
// chrome
// .goto('http://0.0.0.0:6060/#!/Card/12')
// .then(() => chrome.screenshot())
// .then(image => expect(image).toMatchImageSnapshot()));
// it('Card > Headed > Collapsed', () =>
// chrome
// .goto('http://0.0.0.0:6060/#!/Card/13')
// .then(() => chrome.screenshot())
// .then(image => expect(image).toMatchImageSnapshot()));
// it('Card > Headed', () =>
// chrome
// .goto('http://0.0.0.0:6060/#!/Card/14')
// .then(() => chrome.screenshot())
// .then(image => expect(image).toMatchImageSnapshot()));
// it('Card > Headed > Collapsed', () =>
// chrome
// .goto('http://0.0.0.0:6060/#!/Card/15')
// .then(() => chrome.screenshot())
// .then(image => expect(image).toMatchImageSnapshot()));
// it('Card > Headed', () =>
// chrome
// .goto('http://0.0.0.0:6060/#!/Card/16')
// .then(() => chrome.screenshot())
// .then(image => expect(image).toMatchImageSnapshot()));
// it('Card > Headed > Collapsed', () =>
// chrome
// .goto('http://0.0.0.0:6060/#!/Card/17')
// .then(() => chrome.screenshot())
// .then(image => expect(image).toMatchImageSnapshot()));
// it('Card > Headed', () =>
// chrome
// .goto('http://0.0.0.0:6060/#!/Card/18')
// .then(() => chrome.screenshot())
// .then(image => expect(image).toMatchImageSnapshot()));
// it('Card > Headed > Collapsed', () =>
// chrome
// .goto('http://0.0.0.0:6060/#!/Card/19')
// .then(() => chrome.screenshot())
// .then(image => expect(image).toMatchImageSnapshot()));
// it('Card > Headed', () =>
// chrome
// .goto('http://0.0.0.0:6060/#!/Card/20')
// .then(() => chrome.screenshot())
// .then(image => expect(image).toMatchImageSnapshot()));
// it('Card > Headed > Collapsed', () =>
// chrome
// .goto('http://0.0.0.0:6060/#!/Card/21')
// .then(() => chrome.screenshot())
// .then(image => expect(image).toMatchImageSnapshot()));
// it('Card > Headed', () =>
// chrome
// .goto('http://0.0.0.0:6060/#!/Card/22')
// .then(() => chrome.screenshot())
// .then(image => expect(image).toMatchImageSnapshot()));
// it('Card > Headed > Collapsed', () =>
// chrome
// .goto('http://0.0.0.0:6060/#!/Card/23')
// .then(() => chrome.screenshot())
// .then(image => expect(image).toMatchImageSnapshot()));
// it('Card > Headed', () =>
// chrome
// .goto('http://0.0.0.0:6060/#!/Card/24')
// .then(() => chrome.screenshot())
// .then(image => expect(image).toMatchImageSnapshot()));
});

View File

@ -9,13 +9,15 @@
"dev": "NODE_ENV=development joyent-react-scripts start",
"build": "NODE_ENV=production joyent-react-scripts build",
"fmt": "prettier --write --single-quote *.js src/*.js src/**/*.js",
"lint": "eslint . --fix && stylelint './src/**/*.js'"
"lint-ci": "eslint . --fix --ext .js --ext .md && echo 0 `# stylelint './src/**/*.js'`",
"lint": "eslint . --fix --ext .js --ext .md && echo 0 `# stylelint './src/**/*.js'`",
"prepublish": "echo 0"
},
"dependencies": {
"history": "^4.7.2",
"joyent-ui-toolkit": "^2.0.0",
"joyent-ui-toolkit": "^2.0.1",
"pascal-case": "^2.0.1",
"path-to-regexp": "^2.0.0",
"path-to-regexp": "^2.1.0",
"qs": "^6.5.1",
"react": "^16.0.0",
"react-dom": "^16.0.0",
@ -24,13 +26,13 @@
"react-scripts": "1.0.14",
"redux": "^3.7.2",
"redux-form": "^7.1.1",
"styled-components": "^2.2.1"
"styled-components": "^2.2.2"
},
"devDependencies": {
"babel-preset-joyent-portal": "^3.3.3",
"eslint": "^4.8.0",
"eslint-config-joyent-portal": "3.1.0",
"joyent-react-scripts": "^2.2.1",
"eslint": "^4.9.0",
"eslint-config-joyent-portal": "^3.2.0",
"joyent-react-scripts": "^2.6.0",
"prettier": "^1.7.4",
"stylelint": "^8.2.0",
"stylelint-config-joyent-portal": "^2.0.1"

View File

@ -10,18 +10,17 @@
"REACT_APP_GQL_PORT=4000 PORT=3069 REACT_APP_GQL_PROTOCOL=http joyent-react-scripts start",
"start": "PORT=3069 joyent-react-scripts start",
"build": "NODE_ENV=production joyent-react-scripts build",
"lint:css": "echo 0 `# stylelint './src/**/*.js'`",
"lint:js": "eslint . --fix",
"lint": "redrun -s lint:*",
"test": "NODE_ENV=test ./test/run --env=jsdom",
"lint-ci": "eslint . --ext .js --ext .md && stylelint './src/**/*.js'",
"lint": "eslint . --fix --ext .js --ext .md && stylelint './src/**/*.js'",
"test-ci": "echo 0 `# NODE_ENV=test ./test/run --env=jsdom --coverage`",
"test": "NODE_ENV=test ./test/run --env=jsdom",
"prepublish": "echo 0"
},
"dependencies": {
"apollo": "^0.2.2",
"graphql-tag": "^2.4.2",
"graphql-tag": "^2.5.0",
"jest-cli": "^21.0.1",
"joyent-ui-toolkit": "^2.0.0",
"joyent-ui-toolkit": "^2.0.1",
"lodash.isempty": "^4.4.0",
"normalized-styled-components": "^1.0.17",
"prop-types": "^15.6.0",
@ -31,11 +30,11 @@
"react-redux": "^5.0.6",
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
"react-styled-flexboxgrid": "^2.0.3",
"react-styled-flexboxgrid": "^2.1.0",
"redux": "^3.7.2",
"redux-form": "^7.1.1",
"remcalc": "^1.0.9",
"styled-components": "^2.2.1",
"styled-components": "^2.2.2",
"styled-is": "^1.1.0",
"unitcalc": "^1.1.1"
},
@ -46,9 +45,9 @@
"babel-plugin-inline-react-svg": "^0.4.0",
"babel-preset-joyent-portal": "^3.3.3",
"commitizen": "^2.9.6",
"cross-env": "^5.0.5",
"eslint": "^4.8.0",
"eslint-config-joyent-portal": "3.1.0",
"cross-env": "^5.1.0",
"eslint": "^4.9.0",
"eslint-config-joyent-portal": "^3.2.0",
"jest": "^21.2.1",
"jest-alias-preprocessor": "^1.1.1",
"jest-cli": "^21.2.1",
@ -56,9 +55,9 @@
"jest-junit": "^3.1.0",
"jest-matcher-utils": "^21.2.1",
"jest-snapshot": "^21.2.1",
"jest-styled-components": "^4.7.0",
"jest-styled-components": "^4.9.0",
"jest-transform-graphql": "^2.1.0",
"joyent-react-scripts": "^2.3.0",
"joyent-react-scripts": "^2.6.0",
"lodash.sortby": "^4.7.0",
"mz": "^2.7.0",
"react-scripts": "^1.0.14",

1009
yarn.lock

File diff suppressed because it is too large Load Diff