fix list-item

fixes #281
This commit is contained in:
Sérgio Ramos 2017-02-27 15:41:08 +00:00 committed by Judit Greskovits
parent 017f133611
commit 7f2c92b730
19 changed files with 379 additions and 265 deletions

View File

@ -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 = ({
<ListItemTitle>{service.name}</ListItemTitle>
) : (
<ListItemTitle>
<Link to={to}>
{AnchorFn(
<Anchor secondary>
{service.name}
</Anchor>
)}
<Link secondary to={to}>
{service.name}
</Link>
</ListItemTitle>
);

View File

@ -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
);

View File

@ -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 = [{

View File

@ -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;

View File

@ -160,11 +160,14 @@ const Button = (props) => {
const View = Views.reduce((sel, view) => sel ? sel : view(), null);
return (
<View {...props} />
<View {...props}>
{props.children}
</View>
);
};
Button.propTypes = {
children: React.PropTypes.node,
href: React.PropTypes.string,
rr: React.PropTypes.bool,
to: React.PropTypes.string

View File

@ -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
}) => (
<StyledTitle
{...props}
name='list-item-description'
xs={xs(props)}
>
<InnerDescription collapsed={collapsed}>
{children}
</InnerDescription>
</StyledTitle>
);
}) => {
const render = ({
collapsed = false
}) => (
<StyledTitle
collapsed={collapsed}
name='list-item-description'
xs={collapsed ? 6 : 12}
>
<InnerDescription collapsed={collapsed}>
{children}
</InnerDescription>
</StyledTitle>
);
return (
<Subscriber channel='list-item'>
{render}
</Subscriber>
);
};
Description.propTypes = {
children: React.PropTypes.node,

View File

@ -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};
`;

View File

@ -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) => (
<StyledItem
collapsed
headed
name='list-item-header'
>
{addFromHeader(props.children)}
</StyledItem>
);
return (
<Broadcast channel='list-item' value={newValue}>
<StyledItem
collapsed
name='list-item-header'
headed
{...props}
>
{children}
</StyledItem>
</Broadcast>
);
};
return (
<Subscriber channel='list-item'>
{render}
</Subscriber>
);
};
Header.propTypes = {
children: React.PropTypes.node

View File

@ -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
}) => (
<Item name='list-item' {...props}>
{children}
</Item>
))
);
const Item = ({
children,
collapsed = false,
headed = false,
...props
}) => {
const render = (value) => {
const newValue = {
fromHeader: (value || {}).fromHeader,
headed,
collapsed
};
return (
<Broadcast channel='list-item' value={newValue}>
<StyledItem
name='list-item'
collapsed={collapsed}
headed={headed}
{...props}
>
{children}
</StyledItem>
</Broadcast>
);
};
return (
<Subscriber channel='list-item'>
{render}
</Subscriber>
);
};
Item.propTypes = {
children: React.PropTypes.node,
collapsed: React.PropTypes.bool,
headed: React.PropTypes.bool
};
export default Baseline(
Item
);

View File

@ -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 = (
<Column
md={md(props)}
name='list-item-meta'
xs={12}
{...props}
>
<InnerRow collapsed={collapsed}>
{children}
</InnerRow>
</Column>
);
const render = ({
collapsed = false,
fromHeader = false,
headed = false
}) => {
const meta = (
<Column
name='list-item-meta'
xs={collapsed ? 12 : 6}
collapsed={collapsed}
fromHeader={fromHeader}
headed={headed}
{...props}
>
<InnerRow collapsed={collapsed}>
{children}
</InnerRow>
</Column>
);
return !props.fromHeader ? meta : (
<View collapsed fromHeader>
{meta}
</View>
return !fromHeader ? meta : (
<View collapsed fromHeader>
{meta}
</View>
);
};
return (
<Subscriber channel='list-item'>
{render}
</Subscriber>
);
});
};
Meta.propTypes = {
children: React.PropTypes.node,
collapsed: React.PropTypes.bool,
fromHeader: React.PropTypes.bool,
headed: React.PropTypes.bool
};
export default Baseline(
Meta

View File

@ -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,
}];
min: 30
}];

View File

@ -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
}) => (
<Nav
fromHeader={fromHeader}
name='list-item-options'
>
<StyledButton
rect
secondary={!fromHeader}
{...props}
>
{children}
</StyledButton>
</Nav>
));
}) => {
const render = ({
fromHeader = false,
collapsed = false
}) => (
<Nav fromHeader={fromHeader} name='list-item-options'>
<StyledButton
secondary={!fromHeader}
collapsed={collapsed}
rect
{...props}
>
{children}
</StyledButton>
</Nav>
);
return (
<Subscriber channel='list-item'>
{render}
</Subscriber>
);
};
Options.propTypes = {
children: React.PropTypes.node
children: React.PropTypes.node,
collapsed: React.PropTypes.bool,
fromHeader: React.PropTypes.bool
};
export default Baseline(

View File

@ -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
}) => (
<StyledColumn
md={6}
name='list-item-outlet'
xs={12}
{...props}
>
{children}
</StyledColumn>
);
}) => {
const render = ({
collapsed = false
}) => (
<StyledColumn
name='list-item-outlet'
collapsed={collapsed}
xs={6}
{...props}
>
{children}
</StyledColumn>
);
return (
<Subscriber channel='list-item'>
{render}
</Subscriber>
);
};
Outlet.propTypes = {
children: React.PropTypes.node
children: React.PropTypes.node,
collapsed: React.PropTypes.bool
};
export default Baseline(

View File

@ -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
}) => (
<StyledTitle name='list-item-subtitle' {...props}>
<Span fromHeader={fromHeader}>
{children}
</Span>
</StyledTitle>
);
}) => {
const render = ({
fromHeader = false,
collapsed = false
}) => (
<StyledTitle
name='list-item-subtitle'
fromHeader={fromHeader}
collapsed={collapsed}
{...props}
>
<Span fromHeader={fromHeader} collapsed={collapsed}>
{children}
</Span>
</StyledTitle>
);
return (
<Subscriber channel='list-item'>
{render}
</Subscriber>
);
};
Subtitle.propTypes = {
children: React.PropTypes.node,
collapsed: React.PropTypes.bool,
fromHeader: React.PropTypes.bool
};

View File

@ -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 : (
<Span>{children}</Span>
);
return (
const render = ({
collapsed = false,
fromHeader = false
}) => (
<Container
collapsed={collapsed}
fromHeader={fromHeader}
name='list-item-title'
xs={xs({
collapsed
})}
xs={collapsed ? 6 : 12}
{...props}
>
{_children}
</Container>
);
return (
<Subscriber channel='list-item'>
{render}
</Subscriber>
);
};
Title.propTypes = {
children: React.PropTypes.node,
collapsed: React.PropTypes.bool
collapsed: React.PropTypes.bool,
fromHeader: React.PropTypes.bool
};
export default Baseline(

View File

@ -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 : (
<StyledView name='list-item-view' {...props}>
{props.children}
</StyledView>
const hide = (
newValue.headed &&
!newValue.fromHeader &&
newValue.collapsed
);
return hide ? null : (
<StyledView name='list-item-view' {...newValue}>
{children}
</StyledView>
);
};
return (
<Subscriber channel='list-item'>
{render}
</Subscriber>
);
};
@ -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;

View File

@ -97,3 +97,13 @@ export const clearfix = css`
clear:both;
}
`;
export {
libreFranklin,
libreFranklinSemiBold,
libreFranklinBold,
bold,
regular,
titleColor,
bodyColor
} from './typography';

View File

@ -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
};

View File

@ -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 (
<Component {...props}>
{_children}
</Component>
);
};