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 React = require('react');
const Styled = require('styled-components');
const Title = require('./title');
const { const {
default: styled 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 = { module.exports = {
ListItem: require('./item'),
ListItemView: require('./view'),
ListItemTitle: require('./title'),
ListItemSubTitle: require('./subtitle'),
ListItemDescription: require('./description'), ListItemDescription: require('./description'),
ListItemHeader: require('./header'),
ListItem: require('./item'),
ListItemMeta: require('./meta'), ListItemMeta: require('./meta'),
ListItemOptions: require('./options'),
ListItemOutlet: require('./outlet'), 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 constants = require('../../shared/constants');
const fns = require('../../shared/functions'); const fns = require('../../shared/functions');
const React = require('react'); const React = require('react');
const Row = require('../row'); const Row = require('../row');
const Styled = require('styled-components'); const Styled = require('styled-components');
const transferProps = require('./transfer-props');
const { const {
boxes, boxes,
@ -18,16 +18,28 @@ const {
default: styled default: styled
} = 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)` const Item = styled(Row)`
position: relative;
height: ${height} height: ${height}
box-shadow: ${boxes.bottomShaddow}; box-shadow: ${shadow};
border: 1px solid ${colors.borderSecondary}; border: 1px solid ${colors.borderSecondary};
background-color: ${colors.brandSecondary}; background-color: ${colors.brandSecondary};
margin-bottom: ${remcalc(10)};
`; `;
module.exports = Collapsed((props) => ( module.exports = transferProps([
'collapsed',
'headed'
], (props) => (
<Item name='list-item' {...props}> <Item name='list-item' {...props}>
{props.children} {props.children}
</Item> </Item>

View File

@ -1,8 +1,9 @@
const Collapsed = require('./collapsed');
const Column = require('../column'); const Column = require('../column');
const Styled = require('styled-components');
const React = require('react'); const React = require('react');
const Row = require('../row'); const Row = require('../row');
const Styled = require('styled-components');
const transferProps = require('./transfer-props');
const View = require('./view');
const { const {
default: styled default: styled
@ -14,7 +15,12 @@ const InnerRow = styled(Row)`
height: 100%; height: 100%;
`; `;
module.exports = Collapsed((props) => ( module.exports = transferProps([
'collapsed',
'headed',
'fromHeader'
], (props) => {
const meta = (
<Column <Column
name='list-item-meta' name='list-item-meta'
xs={xs(props)} xs={xs(props)}
@ -24,4 +30,11 @@ module.exports = Collapsed((props) => (
{props.children} {props.children}
</InnerRow> </InnerRow>
</Column> </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 constants = require('../../shared/constants');
const fns = require('../../shared/functions'); const fns = require('../../shared/functions');
const React = require('react'); const React = require('react');
const transferProps = require('./transfer-props');
const Styled = require('styled-components'); const Styled = require('styled-components');
const { const {
@ -16,11 +17,17 @@ const {
default: styled default: styled
} = 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` const Nav = styled.nav`
flex: 0 0 ${remcalc(47)}; flex: 0 0 ${remcalc(47)};
border-left: 1px solid ${colors.borderSecondary}; border-left: 1px solid ${borderLeftColor};
`; `;
const StyledButton = styled(Button)` const StyledButton = styled(Button)`
@ -44,17 +51,24 @@ const StyledButton = styled(Button)`
} }
`; `;
const Options = (props) => ( const Options = transferProps([
<Nav name='list-item-options'> 'collapsed',
'headed',
'fromHeader'
], (props) => (
<Nav
fromHeader={props.fromHeader}
name='list-item-options'
>
<StyledButton <StyledButton
rect rect
secondary secondary={!props.fromHeader}
{...props} {...props}
> >
{props.children} {props.children}
</StyledButton> </StyledButton>
</Nav> </Nav>
); ));
Options.propTypes = { Options.propTypes = {
children: React.PropTypes.node children: React.PropTypes.node

View File

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

View File

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

View File

@ -16,6 +16,10 @@ const {
default: styled default: styled
} = Styled; } = Styled;
const color = (props) => !props.fromHeader
? colors.brandSecondaryColor
: colors.brandPrimaryColor;
const justify = (props) => props.collapsed ? 'center' : 'flex-start'; const justify = (props) => props.collapsed ? 'center' : 'flex-start';
const width = (props) => props.collapsed ? 'auto' : '100%'; const width = (props) => props.collapsed ? 'auto' : '100%';
const direction = (props) => props.collapsed ? 'column' : 'row'; const direction = (props) => props.collapsed ? 'column' : 'row';
@ -26,7 +30,7 @@ const Container = styled.div`
font-size: ${remcalc(16)}; font-size: ${remcalc(16)};
font-weight: 600; font-weight: 600;
line-height: 1.5; line-height: 1.5;
color: ${colors.brandSecondaryColor}; color: ${color};
display: flex; display: flex;
flex-direction: ${direction}; 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 React = require('react');
const Row = require('../row'); const Row = require('../row');
const Styled = require('styled-components'); const Styled = require('styled-components');
const {
remcalc
} = fns;
const { const {
default: styled default: styled
} = 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)` const View = styled(Row)`
flex: 1; flex: 1;
margin: 0; margin: 0;
height: 100%; height: 100%;
padding-top: ${paddingTop};
display: ${display};
`; `;
module.exports = Collapsed((props) => ( module.exports = transferProps([
'collapsed',
'headed',
'fromHeader'
], (props) => (
<View name='list-item-view' {...props}> <View name='list-item-view' {...props}>
{props.children} {props.children}
</View> </View>

View File

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

View File

@ -16,14 +16,15 @@ const {
Avatar, Avatar,
Input, Input,
List: { List: {
ListItem,
ListItemView,
ListItemTitle,
ListItemSubTitle,
ListItemDescription, ListItemDescription,
ListItemHeader,
ListItem,
ListItemMeta, ListItemMeta,
ListItemOutlet,
ListItemOptions, ListItemOptions,
ListItemOutlet,
ListItemSubTitle,
ListItemTitle,
ListItemView
}, },
MiniMetric, MiniMetric,
Modal, Modal,
@ -569,4 +570,52 @@ storiesOf('ListItem', module)
</ListItemOptions> </ListItemOptions>
</ListItem> </ListItem>
</Base> </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>
)); ));