diff --git a/frontend/src/components/service/item.js b/frontend/src/components/service/item.js index 911c7af9..51577ade 100644 --- a/frontend/src/components/service/item.js +++ b/frontend/src/components/service/item.js @@ -1,8 +1,7 @@ import React from 'react'; -import { Link } from 'react-router-dom'; import forceArray from 'force-array'; -import Anchor, { fn as AnchorFn } from '@ui/components/anchor'; +import { Link } from '@ui/components/anchor'; import MetricsOutlet from '@components/metrics-outlet'; import PropTypes from '@root/prop-types'; @@ -40,12 +39,8 @@ const ServiceItem = ({ {service.name} ) : ( - - {AnchorFn( - - {service.name} - - )} + + {service.name} ); diff --git a/ui/src/components/anchor/index.js b/ui/src/components/anchor/index.js index f5cb25f4..a7967e65 100644 --- a/ui/src/components/anchor/index.js +++ b/ui/src/components/anchor/index.js @@ -1,22 +1,29 @@ import { is } from '../../shared/functions'; import { colors } from '../../shared/constants'; import { Baseline } from '../../shared/composers'; -import styled from 'styled-components'; -import React from 'react'; +import { Link as BaseLink } from 'react-router-dom'; +import styled, { css } from 'styled-components'; -const StyledAnchor = styled.a` - color: ${colors.base.primary} !important; +const style = css` + color: ${colors.base.primary}; ${is('secondary')` - color: ${colors.base.secondary} !important; + color: ${colors.base.white}; `} `; +const StyledAnchor = styled.a` + ${style} +`; + +const StyledLink = styled(BaseLink)` + ${style} +`; + export default Baseline( StyledAnchor ); -export const fn = (element) => (props) => React.cloneElement(element, { - ...element.props, - ...props -}, element.props.children); +export const Link = Baseline( + StyledLink +); diff --git a/ui/src/components/base-elements/index.js b/ui/src/components/base-elements/index.js index cbcb0fc3..b6ad1891 100644 --- a/ui/src/components/base-elements/index.js +++ b/ui/src/components/base-elements/index.js @@ -1,12 +1,10 @@ /* eslint react/prop-types: 0 */ +import { remcalc } from '../../shared/functions'; +import { Baseline, bold } from '../../shared/composers'; import styled, { css } from 'styled-components'; import React from 'react'; -import { remcalc } from '../../shared/functions'; -import { Baseline } from '../../shared/composers'; -import { bold } from '../../shared/composers/typography'; - // If specificity is an issue (i.e nested elements) check base/index.js first // before using !important const elements = [{ diff --git a/ui/src/components/base/index.js b/ui/src/components/base/index.js index 46bb7a97..4b55bd17 100644 --- a/ui/src/components/base/index.js +++ b/ui/src/components/base/index.js @@ -1,13 +1,8 @@ import { colors } from '../../shared/constants'; +import { libreFranklin, bodyColor, regular } from '../../shared/composers'; import styled from 'styled-components'; import global from './global'; -import { - libreFranklin, - bodyColor, - regular -} from '../../shared/composers/typography'; - export default styled.div` font-size: 1rem; line-height: 1.5; diff --git a/ui/src/components/button/index.js b/ui/src/components/button/index.js index 7b1d5c2a..1fcccaa5 100644 --- a/ui/src/components/button/index.js +++ b/ui/src/components/button/index.js @@ -160,11 +160,14 @@ const Button = (props) => { const View = Views.reduce((sel, view) => sel ? sel : view(), null); return ( - + + {props.children} + ); }; Button.propTypes = { + children: React.PropTypes.node, href: React.PropTypes.string, rr: React.PropTypes.bool, to: React.PropTypes.string diff --git a/ui/src/components/list/description.js b/ui/src/components/list/description.js index 6e8eea06..938dcc42 100644 --- a/ui/src/components/list/description.js +++ b/ui/src/components/list/description.js @@ -1,49 +1,55 @@ +import { Subscriber } from 'react-broadcast'; import { Baseline } from '../../shared/composers'; -import { remcalc, is } from '../../shared/functions'; +import { remcalc, is, isNot } from '../../shared/functions'; import styled from 'styled-components'; import Title from './title'; import React from 'react'; -const xs = (props) => props.collapsed - ? 6 - : 12; - const StyledTitle = styled(Title)` - ${is('collapsed')` + font-weight: normal; + flex-grow: 2; + + ${isNot('collapsed')` position: absolute; bottom: 0; padding-bottom: ${remcalc(12)}; padding-top: 0; `}; - - font-weight: normal; - flex-grow: 2; `; const InnerDescription = styled.div` justify-content: flex-start; ${is('collapsed')` - margin-left: auto; justify-content: flex-end; + margin-left: auto; `}; `; const Description = ({ children, - collapsed, ...props -}) => ( - - - {children} - - -); +}) => { + const render = ({ + collapsed = false + }) => ( + + + {children} + + + ); + + return ( + + {render} + + ); +}; Description.propTypes = { children: React.PropTypes.node, diff --git a/ui/src/components/list/group-view.js b/ui/src/components/list/group-view.js index 1607bb6f..3108e578 100644 --- a/ui/src/components/list/group-view.js +++ b/ui/src/components/list/group-view.js @@ -1,15 +1,13 @@ import { Baseline } from '../../shared/composers'; import { colors } from '../../shared/constants'; import { remcalc } from '../../shared/functions'; -import { raw as View } from './view'; +import View from './view'; import styled from 'styled-components'; const GroupView = styled(View)` display: block; - padding-top: ${remcalc(62)}; - padding-left: ${remcalc(23)}; - padding-right: ${remcalc(23)}; - padding-bottom: ${remcalc(5)}; + padding: ${remcalc(62, 23, 5, 23)}; + background-color: ${colors.inactive.default}; `; diff --git a/ui/src/components/list/header.js b/ui/src/components/list/header.js index 569830eb..4d5d0ded 100644 --- a/ui/src/components/list/header.js +++ b/ui/src/components/list/header.js @@ -1,5 +1,6 @@ import React from 'react'; import styled from 'styled-components'; +import { Broadcast, Subscriber } from 'react-broadcast'; import { remcalc } from '../../shared/functions'; import { Baseline } from '../../shared/composers'; import { colors } from '../../shared/constants'; @@ -8,9 +9,8 @@ import Item from './item'; const StyledItem = styled(Item)` position: absolute; - background-color: #3B4AAF; - - border: solid ${remcalc(1)} #2D3884; + background-color: ${colors.base.primary}; + border: solid ${remcalc(1)} ${colors.base.primaryDesaturatedActive}; box-shadow: none; width: calc(100% + ${remcalc(2)}); @@ -19,29 +19,38 @@ const StyledItem = styled(Item)` top: ${remcalc(-1)}; left: ${remcalc(-1)}; right: ${remcalc(-1)}; - - & [name="list-item-subtitle"], - & [name="list-item-title"] { - color: ${colors.base.white}; - } `; -const addFromHeader = (children) => React.Children.map(children, (c) => { - return React.cloneElement(c, { - ...c.props, - fromHeader: true - }); -}); +const Header = ({ + children, + ...props +}) => { + const render = (value) => { + const newValue = { + ...value, + fromHeader: true + }; -const Header = (props) => ( - - {addFromHeader(props.children)} - -); + return ( + + + {children} + + + ); + }; + + return ( + + {render} + + ); +}; Header.propTypes = { children: React.PropTypes.node diff --git a/ui/src/components/list/item.js b/ui/src/components/list/item.js index aa004125..e5bd5490 100644 --- a/ui/src/components/list/item.js +++ b/ui/src/components/list/item.js @@ -1,19 +1,19 @@ import styled from 'styled-components'; -import transferProps from '../../shared/transfer-props'; +import { Broadcast, Subscriber } from 'react-broadcast'; import { Baseline } from '../../shared/composers'; import { boxes, colors } from '../../shared/constants'; -import { remcalc, is } from '../../shared/functions'; +import { remcalc, is, isAnd } from '../../shared/functions'; import Row from '../row'; import React from 'react'; const paper = ` - 0 ${remcalc(8)} 0 ${remcalc(-5)} ${colors.base.grey}, + 0 ${remcalc(8)} 0 ${remcalc(-5)} ${colors.base.background}, 0 ${remcalc(8)} ${remcalc(1)} ${remcalc(-4)} ${colors.base.grey}, - 0 ${remcalc(16)} 0 ${remcalc(-10)} ${colors.base.grey}, + 0 ${remcalc(16)} 0 ${remcalc(-10)} ${colors.base.background}, 0 ${remcalc(16)} ${remcalc(1)} ${remcalc(-9)} ${colors.base.grey}; `; -const Item = styled(Row)` +const StyledItem = styled(Row)` position: relative; height: auto; min-height: ${remcalc(126)}; @@ -23,35 +23,65 @@ const Item = styled(Row)` box-shadow: ${boxes.bottomShaddow}; ${is('collapsed')` - height: ${remcalc(48)}; min-height: auto; - - ${is('headed')` - box-shadow: ${boxes.bottomShaddowDarker}; - `}; + height: ${remcalc(48)}; + margin-bottom: ${remcalc(16)}; `}; - ${is('stacked')` - box-shadow: ${paper}; - margin-bottom: ${remcalc(16)}; + ${isAnd('collapsed', 'headed')` + box-shadow: ${boxes.bottomShaddowDarker}; `}; ${is('flat')` box-shadow: none; `}; + + ${is('stacked')` + margin-bottom: ${remcalc(16)}; + box-shadow: ${paper}; + `}; `; -export default Baseline( - transferProps([ - 'collapsed', - 'headed' - ], ({ - children, - ...props - }) => ( - - {children} - - )) -); +const Item = ({ + children, + collapsed = false, + headed = false, + ...props +}) => { + const render = (value) => { + const newValue = { + fromHeader: (value || {}).fromHeader, + headed, + collapsed + }; + return ( + + + {children} + + + ); + }; + + return ( + + {render} + + ); +}; + +Item.propTypes = { + children: React.PropTypes.node, + collapsed: React.PropTypes.bool, + headed: React.PropTypes.bool +}; + +export default Baseline( + Item +); diff --git a/ui/src/components/list/meta.js b/ui/src/components/list/meta.js index a775d9de..6e2cbba2 100644 --- a/ui/src/components/list/meta.js +++ b/ui/src/components/list/meta.js @@ -1,5 +1,5 @@ import styled from 'styled-components'; -import transferProps from '../../shared/transfer-props'; +import { Subscriber } from 'react-broadcast'; import { Baseline } from '../../shared/composers'; import { is } from '../../shared/functions'; import Column from '../column'; @@ -7,10 +7,6 @@ import Row from '../row'; import View from './view'; import React from 'react'; -const md = (props) => props.collapsed - ? 12 - : 6; - const InnerRow = styled(Row)` display: block; height: 100%; @@ -20,34 +16,50 @@ const InnerRow = styled(Row)` `}; `; -const Meta = transferProps([ - 'collapsed', - 'headed', - 'fromHeader' -], ({ +const Meta = ({ children, - collapsed, ...props }) => { - const meta = ( - - - {children} - - - ); + const render = ({ + collapsed = false, + fromHeader = false, + headed = false + }) => { + const meta = ( + + + {children} + + + ); - return !props.fromHeader ? meta : ( - - {meta} - + return !fromHeader ? meta : ( + + {meta} + + ); + }; + + return ( + + {render} + ); -}); +}; + +Meta.propTypes = { + children: React.PropTypes.node, + collapsed: React.PropTypes.bool, + fromHeader: React.PropTypes.bool, + headed: React.PropTypes.bool +}; export default Baseline( Meta diff --git a/ui/src/components/list/mini-metric-data.js b/ui/src/components/list/mini-metric-data.js index 51666a20..89ba46c5 100644 --- a/ui/src/components/list/mini-metric-data.js +++ b/ui/src/components/list/mini-metric-data.js @@ -1,105 +1,103 @@ -/*eslint-disable */ - export default [{ firstQuartile: 15, thirdQuartile: 15, median: 15, max: 15, - min: 15, + min: 15 }, { firstQuartile: 26, thirdQuartile: 26, median: 26, max: 26, - min: 26, + min: 26 }, { firstQuartile: 17, thirdQuartile: 17, median: 17, max: 17, - min: 17, + min: 17 }, { firstQuartile: 15, thirdQuartile: 25, median: 19, max: 19, - min: 20, + min: 20 }, { firstQuartile: 19, thirdQuartile: 25, median: 21, max: 20, - min: 25, + min: 25 }, { firstQuartile: 24, thirdQuartile: 30, median: 25, max: 26, - min: 27, + min: 27 }, { firstQuartile: 28, thirdQuartile: 34, median: 30, max: 30, - min: 30, + min: 30 }, { firstQuartile: 30, thirdQuartile: 45, median: 35, max: 40, - min: 40, + min: 40 }, { firstQuartile: 20, thirdQuartile: 55, median: 45, max: 44, - min: 44, + min: 44 }, { firstQuartile: 55, thirdQuartile: 55, median: 55, max: 55, - min: 55, + min: 55 }, { firstQuartile: 57, thirdQuartile: 56, median: 57, max: 58, - min: 57, + min: 57 }, { firstQuartile: 57, thirdQuartile: 56, median: 56, max: 56, - min: 56, + min: 56 }, { firstQuartile: 60, thirdQuartile: 56, median: 60, max: 60, - min: 60, + min: 60 }, { firstQuartile: 57, thirdQuartile: 57, median: 57, max: 57, - min: 57, + min: 57 }, { firstQuartile: 57, thirdQuartile: 55, median: 55, max: 55, - min: 55, + min: 55 }, { firstQuartile: 20, thirdQuartile: 45, median: 45, max: 45, - min: 45, + min: 45 }, { firstQuartile: 15, thirdQuartile: 40, median: 30, max: 49, - min: 30, -}]; \ No newline at end of file + min: 30 +}]; diff --git a/ui/src/components/list/options.js b/ui/src/components/list/options.js index 62adc688..73ffd80e 100644 --- a/ui/src/components/list/options.js +++ b/ui/src/components/list/options.js @@ -1,14 +1,15 @@ +import { Subscriber } from 'react-broadcast'; import styled from 'styled-components'; import { Baseline } from '../../shared/composers'; import { colors } from '../../shared/constants'; import { remcalc, is } from '../../shared/functions'; -import transferProps from '../../shared/transfer-props'; import Button from '../button'; import React from 'react'; const Nav = styled.nav` flex: 0 0 ${remcalc(47)}; border-left: ${remcalc(1)} solid ${colors.base.grey}; + box-sizing: border-box; ${is('fromHeader')` border-left-color: ${colors.base.primary}; @@ -19,8 +20,13 @@ const StyledButton = styled(Button)` border-width: 0; box-shadow: none; width: 100%; + min-width: auto; height: ${remcalc(124)}; + display: flex; + overflow-x: visible; + overflow-y: visible; + ${is('collapsed')` height: ${remcalc(46)}; `}; @@ -40,31 +46,37 @@ const StyledButton = styled(Button)` } `; -const Options = transferProps([ - 'collapsed', - 'headed', - 'fromHeader' -], ({ +const Options = ({ children, - fromHeader, ...props -}) => ( - -)); +}) => { + const render = ({ + fromHeader = false, + collapsed = false + }) => ( + + ); + + return ( + + {render} + + ); +}; Options.propTypes = { - children: React.PropTypes.node + children: React.PropTypes.node, + collapsed: React.PropTypes.bool, + fromHeader: React.PropTypes.bool }; export default Baseline( diff --git a/ui/src/components/list/outlet.js b/ui/src/components/list/outlet.js index 6ad7bfcb..72bfb3fa 100644 --- a/ui/src/components/list/outlet.js +++ b/ui/src/components/list/outlet.js @@ -1,3 +1,4 @@ +import { Subscriber } from 'react-broadcast'; import { is } from '../../shared/functions'; import { Baseline } from '../../shared/composers'; import Column from '../column'; @@ -15,19 +16,30 @@ const StyledColumn = styled(Column)` const Outlet = ({ children, ...props -}) => ( - - {children} - -); +}) => { + const render = ({ + collapsed = false + }) => ( + + {children} + + ); + + return ( + + {render} + + ); +}; Outlet.propTypes = { - children: React.PropTypes.node + children: React.PropTypes.node, + collapsed: React.PropTypes.bool }; export default Baseline( diff --git a/ui/src/components/list/subtitle.js b/ui/src/components/list/subtitle.js index 47c7429e..c470bb4b 100644 --- a/ui/src/components/list/subtitle.js +++ b/ui/src/components/list/subtitle.js @@ -1,6 +1,8 @@ +import { Subscriber } from 'react-broadcast'; import styled from 'styled-components'; -import { Baseline } from '../../shared/composers'; +import { Baseline, regular } from '../../shared/composers'; import { remcalc, is } from '../../shared/functions'; +import { colors } from '../../shared/constants'; import Title from './title'; import React from 'react'; @@ -18,12 +20,18 @@ const Span = styled.span` ${is('collapsed')` display: flex; `}; + + ${is('fromHeader')` + color: ${colors.base.white}; + `}; `; const StyledTitle = styled(Title)` display: inline-block; padding: 0 ${remcalc(18)}; + ${regular}; + ${is('collapsed')` display: flex; padding: 0; @@ -32,18 +40,35 @@ const StyledTitle = styled(Title)` const Subtitle = ({ children, - fromHeader, ...props -}) => ( - - - {children} - - -); +}) => { + const render = ({ + fromHeader = false, + collapsed = false + }) => ( + + + {children} + + + ); + + return ( + + {render} + + ); +}; + Subtitle.propTypes = { children: React.PropTypes.node, + collapsed: React.PropTypes.bool, fromHeader: React.PropTypes.bool }; diff --git a/ui/src/components/list/title.js b/ui/src/components/list/title.js index 545a3308..ed771265 100644 --- a/ui/src/components/list/title.js +++ b/ui/src/components/list/title.js @@ -1,20 +1,18 @@ +import { Subscriber } from 'react-broadcast'; import isString from 'lodash.isstring'; -import { Baseline } from '../../shared/composers'; +import { Baseline, bold } from '../../shared/composers'; import { colors } from '../../shared/constants'; import { remcalc, is } from '../../shared/functions'; import styled from 'styled-components'; import React from 'react'; -const xs = (props) => props.collapsed - ? 6 - : 12; - const Container = styled.div` font-size: ${remcalc(16)}; - font-weight: 600; line-height: 1.5; color: ${colors.base.secondary}; + ${bold} + display: flex; flex-direction: row; justify-content: flex-start; @@ -24,6 +22,10 @@ const Container = styled.div` padding: ${remcalc(12)} ${remcalc(18)} 0 ${remcalc(18)}; + ${is('fromHeader')` + color: ${colors.base.white}; + `}; + ${is('collapsed')` flex-grow: 0; flex-direction: column; @@ -31,10 +33,6 @@ const Container = styled.div` justify-content: center; padding: 0 ${remcalc(18)}; `}; - - ${is('fromHeader')` - color: ${colors.base.primary}; - `}; `; const Span = styled.span` @@ -49,30 +47,38 @@ const Span = styled.span` const Title = ({ children, - collapsed, ...props }) => { const _children = !isString(children) ? children : ( {children} ); - return ( + const render = ({ + collapsed = false, + fromHeader = false + }) => ( {_children} ); + + return ( + + {render} + + ); }; Title.propTypes = { children: React.PropTypes.node, - collapsed: React.PropTypes.bool + collapsed: React.PropTypes.bool, + fromHeader: React.PropTypes.bool }; export default Baseline( diff --git a/ui/src/components/list/view.js b/ui/src/components/list/view.js index c0644f16..1e1d5149 100644 --- a/ui/src/components/list/view.js +++ b/ui/src/components/list/view.js @@ -1,6 +1,6 @@ +import { Subscriber } from 'react-broadcast'; import styled from 'styled-components'; import { Baseline } from '../../shared/composers'; -import transferProps from '../../shared/transfer-props'; import { remcalc, is } from '../../shared/functions'; import Row from '../row'; import React from 'react'; @@ -10,29 +10,48 @@ const StyledView = styled(Row)` margin: 0; height: auto; padding-top: 0; + min-width: auto; ${is('headed')` padding-top: ${remcalc(47)}; `}; - ${is('fromHeader')` - padding-top: 0; - `}; - ${is('collapsed')` height: ${remcalc(48)}; `}; + + ${is('fromHeader')` + padding-top: 0; + `}; `; -const View = (props) => { - const hide = props.headed && - !props.fromHeader && - props.collapsed; +const View = ({ + children, + ...props +}) => { + const render = (value) => { + const newValue = { + ...value, + ...props + }; - return hide ? null : ( - - {props.children} - + const hide = ( + newValue.headed && + !newValue.fromHeader && + newValue.collapsed + ); + + return hide ? null : ( + + {children} + + ); + }; + + return ( + + {render} + ); }; @@ -43,14 +62,6 @@ View.propTypes = { headed: React.PropTypes.bool }; -const BaselineView = Baseline( +export default Baseline( View ); - -export default transferProps([ - 'collapsed', - 'headed', - 'fromHeader' -], BaselineView); - -export const raw = BaselineView; diff --git a/ui/src/shared/composers/index.js b/ui/src/shared/composers/index.js index bd6a1c4d..dfe50c34 100644 --- a/ui/src/shared/composers/index.js +++ b/ui/src/shared/composers/index.js @@ -97,3 +97,13 @@ export const clearfix = css` clear:both; } `; + +export { + libreFranklin, + libreFranklinSemiBold, + libreFranklinBold, + bold, + regular, + titleColor, + bodyColor +} from './typography'; diff --git a/ui/src/shared/functions.js b/ui/src/shared/functions.js index 83086664..152d5d09 100644 --- a/ui/src/shared/functions.js +++ b/ui/src/shared/functions.js @@ -33,14 +33,30 @@ const unitcalc = (...values) => flatten( const cssCalc = (str) => calc(`calc(${str})`); -const is = (prop) => (...args) => (props) => props[prop] - ? css(...args) - : css``; +const is = (prop) => + (...args) => + (props) => props[prop] + ? css(...args) + : css``; + +const isNot = (prop) => + (...args) => + (props) => !props[prop] + ? css(...args) + : css``; + +const isAnd = (...names) => + (...args) => + (props) => names.every((name) => props[name]) + ? css(...args) + : css``; export { unitcalc, remcalc, cssCalc as calc, rndId, - is + is, + isNot, + isAnd }; diff --git a/ui/src/shared/transfer-props.js b/ui/src/shared/transfer-props.js deleted file mode 100644 index 72ef6452..00000000 --- a/ui/src/shared/transfer-props.js +++ /dev/null @@ -1,29 +0,0 @@ -import isString from 'lodash.isstring'; -import React from 'react'; - -const transfer = (parentProps, props) => { -// eslint-disable-next-line react/prop-types - return React.Children.map(props.children, (c) => { - return c && React.cloneElement(c, { - ...c.props, - ...parentProps.reduce((sum, name) => ({ - ...sum, - [name]: props[name] - }), {}) - }); - }); -}; - -export default (parentProps, Component) => (props) => { -// eslint-disable-next-line react/prop-types - const _children = !isString(props.children) - ? transfer(parentProps, props) -// eslint-disable-next-line react/prop-types - : props.children; - - return ( - - {_children} - - ); -};