headed list item ui component

This commit is contained in:
Sérgio Ramos 2017-01-09 18:58:30 +00:00
parent 98933873c1
commit 7b73e82237
14 changed files with 272 additions and 75 deletions

View File

@ -1,18 +0,0 @@
const React = require('react');
module.exports = (Component) => (props) => {
// eslint-disable-next-line react/prop-types
const _children = React.Children.map(props.children, (c) => {
return React.cloneElement(c, {
...c.props,
// eslint-disable-next-line react/prop-types
collapsed: props.collapsed
});
});
return (
<Component {...props}>
{_children}
</Component>
);
};

View File

@ -1,6 +1,6 @@
const Title = require('./title');
const Styled = require('styled-components');
const React = require('react');
const Styled = require('styled-components');
const Title = require('./title');
const {
default: styled

View File

@ -0,0 +1,55 @@
const constants = require('../../shared/constants');
const fns = require('../../shared/functions');
const Item = require('./item');
const React = require('react');
const Styled = require('styled-components');
const {
colors
} = constants;
const {
remcalc
} = fns;
const {
default: styled
} = Styled;
const StyledItem = styled(Item)`
position: absolute;
background-color: ${colors.brandPrimary};
border: solid 1px ${colors.borderPrimary};
box-shadow: none;
width: calc(100% + ${remcalc(2)});
margin: 0;
top: ${remcalc(-1)};
left: ${remcalc(-1)};
right: ${remcalc(-1)};
`;
const addFromHeader = (children) => React.Children.map(children, (c) => {
return React.cloneElement(c, {
...c.props,
fromHeader: true
});
});
const Header = (props) => (
<StyledItem
collapsed
headed
name='list-item-header'
>
{addFromHeader(props.children)}
</StyledItem>
);
Header.propTypes = {
children: React.PropTypes.node
};
module.exports = Header;

View File

@ -1,10 +1,11 @@
module.exports = {
ListItem: require('./item'),
ListItemView: require('./view'),
ListItemTitle: require('./title'),
ListItemSubTitle: require('./subtitle'),
ListItemDescription: require('./description'),
ListItemHeader: require('./header'),
ListItem: require('./item'),
ListItemMeta: require('./meta'),
ListItemOptions: require('./options'),
ListItemOutlet: require('./outlet'),
ListItemOptions: require('./options')
ListItemSubTitle: require('./subtitle'),
ListItemTitle: require('./title'),
ListItemView: require('./view')
};

View File

@ -1,9 +1,9 @@
const Collapsed = require('./collapsed');
const constants = require('../../shared/constants');
const fns = require('../../shared/functions');
const React = require('react');
const Row = require('../row');
const Styled = require('styled-components');
const transferProps = require('./transfer-props');
const {
boxes,
@ -18,16 +18,28 @@ const {
default: styled
} = Styled;
const height = (props) => props.collapsed ? remcalc(48) : remcalc(126);
const height = (props) => props.collapsed
? remcalc(48)
: remcalc(126);
const shadow = (props) => props.collapsed && props.headed
? boxes.bottomShaddowDarker
: boxes.bottomShaddow;
const Item = styled(Row)`
position: relative;
height: ${height}
box-shadow: ${boxes.bottomShaddow};
box-shadow: ${shadow};
border: 1px solid ${colors.borderSecondary};
background-color: ${colors.brandSecondary};
margin-bottom: ${remcalc(10)};
`;
module.exports = Collapsed((props) => (
module.exports = transferProps([
'collapsed',
'headed'
], (props) => (
<Item name='list-item' {...props}>
{props.children}
</Item>

View File

@ -1,8 +1,9 @@
const Collapsed = require('./collapsed');
const Column = require('../column');
const Styled = require('styled-components');
const React = require('react');
const Row = require('../row');
const Styled = require('styled-components');
const transferProps = require('./transfer-props');
const View = require('./view');
const {
default: styled
@ -14,14 +15,26 @@ const InnerRow = styled(Row)`
height: 100%;
`;
module.exports = Collapsed((props) => (
<Column
name='list-item-meta'
xs={xs(props)}
{...props}
>
<InnerRow>
{props.children}
</InnerRow>
</Column>
));
module.exports = transferProps([
'collapsed',
'headed',
'fromHeader'
], (props) => {
const meta = (
<Column
name='list-item-meta'
xs={xs(props)}
{...props}
>
<InnerRow>
{props.children}
</InnerRow>
</Column>
);
return !props.fromHeader ? meta : (
<View collapsed fromHeader>
{meta}
</View>
);
});

View File

@ -2,6 +2,7 @@ const Button = require('../button');
const constants = require('../../shared/constants');
const fns = require('../../shared/functions');
const React = require('react');
const transferProps = require('./transfer-props');
const Styled = require('styled-components');
const {
@ -16,11 +17,17 @@ const {
default: styled
} = Styled;
const height = (props) => props.collapsed ? remcalc(46) : remcalc(124);
const height = (props) => props.collapsed
? remcalc(46)
: remcalc(124);
const borderLeftColor = (props) => !props.fromHeader
? colors.borderSecondary
: colors.borderPrimary;
const Nav = styled.nav`
flex: 0 0 ${remcalc(47)};
border-left: 1px solid ${colors.borderSecondary};
border-left: 1px solid ${borderLeftColor};
`;
const StyledButton = styled(Button)`
@ -44,17 +51,24 @@ const StyledButton = styled(Button)`
}
`;
const Options = (props) => (
<Nav name='list-item-options'>
const Options = transferProps([
'collapsed',
'headed',
'fromHeader'
], (props) => (
<Nav
fromHeader={props.fromHeader}
name='list-item-options'
>
<StyledButton
rect
secondary
secondary={!props.fromHeader}
{...props}
>
{props.children}
</StyledButton>
</Nav>
);
));
Options.propTypes = {
children: React.PropTypes.node

View File

@ -1,25 +1,31 @@
const Column = require('../column');
const Styled = require('styled-components');
const React = require('react');
const Outlet = (props) => {
if (props.collapsed) {
return null;
}
const {
default: styled
} = Styled;
return (
<Column
name='list-item-outlet'
xs={6}
{...props}
>
{props.children}
</Column>
);
};
const display = (props) => props.collapsed
? 'none'
: 'block';
const StyledColumn = styled(Column)`
display: ${display}
`;
const Outlet = (props) => (
<StyledColumn
name='list-item-outlet'
xs={6}
{...props}
>
{props.children}
</StyledColumn>
);
Outlet.propTypes = {
children: React.PropTypes.node,
collapsed: React.PropTypes.bool
children: React.PropTypes.node
};
module.exports = Outlet;

View File

@ -1,11 +1,20 @@
const constants = require('../../shared/constants');
const Title = require('./title');
const React = require('react');
const Styled = require('styled-components');
const {
colors
} = constants;
const {
default: styled
} = Styled;
const color = (props) => props.fromHeader
? colors.brandPrimaryColor
: '#646464';
const Span = styled.span`
display: flex;
flex-direction: column;
@ -15,19 +24,22 @@ const Span = styled.span`
font-style: normal;
font-stretch: normal;
font-size: 14px;
color: #646464;
color: ${color};
`;
const Subtitle = (props) => (
<Title name='list-item-subtitle' {...props}>
<Span>
<Span
fromHeader={props.fromHeader}
>
{props.children}
</Span>
</Title>
);
Subtitle.propTypes = {
children: React.PropTypes.node
children: React.PropTypes.node,
fromHeader: React.PropTypes.bool
};
module.exports = Subtitle;

View File

@ -16,6 +16,10 @@ const {
default: styled
} = Styled;
const color = (props) => !props.fromHeader
? colors.brandSecondaryColor
: colors.brandPrimaryColor;
const justify = (props) => props.collapsed ? 'center' : 'flex-start';
const width = (props) => props.collapsed ? 'auto' : '100%';
const direction = (props) => props.collapsed ? 'column' : 'row';
@ -26,7 +30,7 @@ const Container = styled.div`
font-size: ${remcalc(16)};
font-weight: 600;
line-height: 1.5;
color: ${colors.brandSecondaryColor};
color: ${color};
display: flex;
flex-direction: ${direction};

View File

@ -0,0 +1,29 @@
const isString = require('lodash.isstring');
const React = require('react');
const transfer = (parentProps, props) => {
// eslint-disable-next-line react/prop-types
return React.Children.map(props.children, (c) => {
return React.cloneElement(c, {
...c.props,
...parentProps.reduce((sum, name) => ({
...sum,
[name]: props[name]
}), {})
});
});
};
module.exports = (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>
);
};

View File

@ -1,19 +1,38 @@
const Collapsed = require('./collapsed');
const fns = require('../../shared/functions');
const transferProps = require('./transfer-props');
const React = require('react');
const Row = require('../row');
const Styled = require('styled-components');
const {
remcalc
} = fns;
const {
default: styled
} = Styled;
const paddingTop = (props) => props.headed && !props.fromHeader
? remcalc(47)
: remcalc(0);
const display = (props) => props.headed && !props.fromHeader && props.collapsed
? 'none'
: 'flex';
const View = styled(Row)`
flex: 1;
margin: 0;
height: 100%;
padding-top: ${paddingTop};
display: ${display};
`;
module.exports = Collapsed((props) => (
module.exports = transferProps([
'collapsed',
'headed',
'fromHeader'
], (props) => (
<View name='list-item-view' {...props}>
{props.children}
</View>

View File

@ -3,6 +3,7 @@ const colors = require('./colors');
const boxes = {
borderRadius: '4px',
bottomShaddow: '0 2px 0 0 rgba(0, 0, 0, 0.05)',
bottomShaddowDarker: '0 2px 0 0 rgba(0, 0, 0, 0.1)',
insetShaddow: 'inset 0 3px 0 0 rgba(0, 0, 0, 0.05)',
border: {
checked: `1px solid ${colors.brandPrimary}`,

View File

@ -16,14 +16,15 @@ const {
Avatar,
Input,
List: {
ListItem,
ListItemView,
ListItemTitle,
ListItemSubTitle,
ListItemDescription,
ListItemHeader,
ListItem,
ListItemMeta,
ListItemOutlet,
ListItemOptions,
ListItemOutlet,
ListItemSubTitle,
ListItemTitle,
ListItemView
},
MiniMetric,
Modal,
@ -569,4 +570,52 @@ storiesOf('ListItem', module)
</ListItemOptions>
</ListItem>
</Base>
))
.add('headed', () => (
<Base>
<ListItem headed>
<ListItemHeader>
<ListItemMeta>
<ListItemTitle>Nginx 01</ListItemTitle>
<ListItemSubTitle>4 instances</ListItemSubTitle>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOptions>
</ListItemOptions>
</ListItemHeader>
<ListItemView>
<ListItemMeta>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOutlet>
Metrics
</ListItemOutlet>
</ListItemView>
</ListItem>
</Base>
))
.add('headed collapsed', () => (
<Base>
<ListItem collapsed headed>
<ListItemHeader>
<ListItemMeta>
<ListItemTitle>Nginx 01</ListItemTitle>
<ListItemSubTitle>4 instances</ListItemSubTitle>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOptions>
</ListItemOptions>
</ListItemHeader>
<ListItemView>
<ListItemMeta>
<ListItemDescription>Flags</ListItemDescription>
</ListItemMeta>
<ListItemOutlet>
Metrics
</ListItemOutlet>
</ListItemView>
</ListItem>
</Base>
));