diff --git a/ui/src/components/list/collapsed.js b/ui/src/components/list/collapsed.js
new file mode 100644
index 00000000..c5824212
--- /dev/null
+++ b/ui/src/components/list/collapsed.js
@@ -0,0 +1,18 @@
+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 (
+
+ {_children}
+
+ );
+};
diff --git a/ui/src/components/list/description.js b/ui/src/components/list/description.js
new file mode 100644
index 00000000..35ba6cf8
--- /dev/null
+++ b/ui/src/components/list/description.js
@@ -0,0 +1,43 @@
+const Title = require('./title');
+const Styled = require('styled-components');
+const React = require('react');
+
+const {
+ default: styled
+} = Styled;
+
+const margin = (props) => props.collapsed ? `
+ margin-left: auto;
+` : '';
+
+const justify = (props) => props.collapsed ? 'flex-end' : 'flex-start';
+const xs = (props) => props.collapsed ? 6 : 12;
+
+const StyledTitle = styled(Title)`
+ font-weight: normal !important;
+ flex-grow: 2;
+`;
+
+const InnerDescription = styled.div`
+ ${margin}
+ justify-content: ${justify};
+`;
+
+const Description = (props) => (
+
+
+ {props.children}
+
+
+);
+
+Description.propTypes = {
+ children: React.PropTypes.node,
+ collapsed: React.PropTypes.bool
+};
+
+module.exports = Description;
diff --git a/ui/src/components/list/index.js b/ui/src/components/list/index.js
new file mode 100644
index 00000000..0d79549b
--- /dev/null
+++ b/ui/src/components/list/index.js
@@ -0,0 +1,10 @@
+module.exports = {
+ ListItem: require('./item'),
+ ListItemView: require('./view'),
+ ListItemTitle: require('./title'),
+ ListItemSubTitle: require('./subtitle'),
+ ListItemDescription: require('./description'),
+ ListItemMeta: require('./meta'),
+ ListItemOutlet: require('./outlet'),
+ ListItemOptions: require('./options')
+};
diff --git a/ui/src/components/list/item.js b/ui/src/components/list/item.js
new file mode 100644
index 00000000..e6c11391
--- /dev/null
+++ b/ui/src/components/list/item.js
@@ -0,0 +1,34 @@
+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 {
+ boxes,
+ colors
+} = constants;
+
+const {
+ remcalc
+} = fns;
+
+const {
+ default: styled
+} = Styled;
+
+const height = (props) => props.collapsed ? remcalc(48) : remcalc(126);
+
+const Item = styled(Row)`
+ height: ${height}
+ box-shadow: ${boxes.bottomShaddow};
+ border: 1px solid ${colors.borderSecondary};
+ background-color: ${colors.brandSecondary};
+`;
+
+module.exports = Collapsed((props) => (
+ -
+ {props.children}
+
+));
diff --git a/ui/src/components/list/meta.js b/ui/src/components/list/meta.js
new file mode 100644
index 00000000..1a2bfda6
--- /dev/null
+++ b/ui/src/components/list/meta.js
@@ -0,0 +1,27 @@
+const Collapsed = require('./collapsed');
+const Column = require('../column');
+const Styled = require('styled-components');
+const React = require('react');
+const Row = require('../row');
+
+const {
+ default: styled
+} = Styled;
+
+const xs = (props) => props.collapsed ? 12 : 6;
+
+const InnerRow = styled(Row)`
+ height: 100%;
+`;
+
+module.exports = Collapsed((props) => (
+
+
+ {props.children}
+
+
+));
diff --git a/ui/src/components/list/options.js b/ui/src/components/list/options.js
new file mode 100644
index 00000000..a04c3303
--- /dev/null
+++ b/ui/src/components/list/options.js
@@ -0,0 +1,63 @@
+const Button = require('../button');
+const constants = require('../../shared/constants');
+const fns = require('../../shared/functions');
+const React = require('react');
+const Styled = require('styled-components');
+
+const {
+ colors
+} = constants;
+
+const {
+ remcalc
+} = fns;
+
+const {
+ default: styled
+} = Styled;
+
+const height = (props) => props.collapsed ? remcalc(46) : remcalc(124);
+
+const Nav = styled.nav`
+ flex: 0 0 ${remcalc(47)};
+ border-left: 1px solid ${colors.borderSecondary};
+`;
+
+const StyledButton = styled(Button)`
+ border-width: 0;
+ box-shadow: none;
+ width: 100%;
+ height: ${height}; /* 100% doest work on safari */
+
+ &:focus {
+ border-width: 0;
+ }
+
+ &:hover {
+ border-width: 0;
+ }
+
+ &:active,
+ &:active:hover,
+ &:active:focus {
+ border-width: 0;
+ }
+`;
+
+const Options = (props) => (
+
+);
+
+Options.propTypes = {
+ children: React.PropTypes.node
+};
+
+module.exports = Options;
diff --git a/ui/src/components/list/outlet.js b/ui/src/components/list/outlet.js
new file mode 100644
index 00000000..2ce3bb2c
--- /dev/null
+++ b/ui/src/components/list/outlet.js
@@ -0,0 +1,25 @@
+const Column = require('../column');
+const React = require('react');
+
+const Outlet = (props) => {
+ if (props.collapsed) {
+ return null;
+ }
+
+ return (
+
+ {props.children}
+
+ );
+};
+
+Outlet.propTypes = {
+ children: React.PropTypes.node,
+ collapsed: React.PropTypes.bool
+};
+
+module.exports = Outlet;
diff --git a/ui/src/components/list/subtitle.js b/ui/src/components/list/subtitle.js
new file mode 100644
index 00000000..7d0fd6d6
--- /dev/null
+++ b/ui/src/components/list/subtitle.js
@@ -0,0 +1,33 @@
+const Title = require('./title');
+const React = require('react');
+const Styled = require('styled-components');
+
+const {
+ default: styled
+} = Styled;
+
+const Span = styled.span`
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+
+ font-weight: normal;
+ font-style: normal;
+ font-stretch: normal;
+ font-size: 14px;
+ color: #646464;
+`;
+
+const Subtitle = (props) => (
+
+
+ {props.children}
+
+
+);
+
+Subtitle.propTypes = {
+ children: React.PropTypes.node
+};
+
+module.exports = Subtitle;
\ No newline at end of file
diff --git a/ui/src/components/list/title.js b/ui/src/components/list/title.js
new file mode 100644
index 00000000..f46bb989
--- /dev/null
+++ b/ui/src/components/list/title.js
@@ -0,0 +1,70 @@
+const constants = require('../../shared/constants');
+const fns = require('../../shared/functions');
+const isString = require('lodash.isstring');
+const Styled = require('styled-components');
+const React = require('react');
+
+const {
+ colors
+} = constants;
+
+const {
+ remcalc
+} = fns;
+
+const {
+ default: styled
+} = Styled;
+
+const justify = (props) => props.collapsed ? 'center' : 'flex-start';
+const width = (props) => props.collapsed ? 'auto' : '100%';
+const direction = (props) => props.collapsed ? 'column' : 'row';
+const grow = (props) => props.collapsed ? 0 : 2;
+const xs = (props) => props.collapsed ? 6 : 12;
+
+const Container = styled.div`
+ font-size: ${remcalc(16)};
+ font-weight: 600;
+ line-height: 1.5;
+ color: ${colors.brandSecondaryColor};
+
+ display: flex;
+ flex-direction: ${direction};
+ justify-content: ${justify};
+
+ flex-grow: ${grow};
+ width: ${width};
+
+ padding-left: 0.5rem;
+ padding-right: 0.5rem;
+`;
+
+const Span = styled.span`
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+`;
+
+const Title = (props) => {
+ const _children = !isString(props.children) ? props.children : (
+ {props.children}
+ );
+
+ return (
+
+ {_children}
+
+ );
+};
+
+Title.propTypes = {
+ children: React.PropTypes.node,
+ collapsed: React.PropTypes.bool
+};
+
+module.exports = Title;
diff --git a/ui/src/components/list/view.js b/ui/src/components/list/view.js
new file mode 100644
index 00000000..c2c4c077
--- /dev/null
+++ b/ui/src/components/list/view.js
@@ -0,0 +1,20 @@
+const Collapsed = require('./collapsed');
+const React = require('react');
+const Row = require('../row');
+const Styled = require('styled-components');
+
+const {
+ default: styled
+} = Styled;
+
+const View = styled(Row)`
+ flex: 1;
+ margin: 0;
+ height: 100%;
+`;
+
+module.exports = Collapsed((props) => (
+
+ {props.children}
+
+));
diff --git a/ui/src/components/radio-group/index.js b/ui/src/components/radio-group/index.js
index ea442f3e..6bb576c1 100644
--- a/ui/src/components/radio-group/index.js
+++ b/ui/src/components/radio-group/index.js
@@ -12,7 +12,7 @@ const Item = require('./item');
const find = require('lodash.find');
const classNames = require('classnames');
const React = require('react');
-const styles = require('./style.css');
+// const styles = require('./style.css');
const RadioGroup = React.createClass({
propTypes: {
@@ -93,8 +93,7 @@ const RadioGroup = React.createClass({
} = this;
const cn = classNames(
- className,
- styles.group
+ className
);
const _children = React.Children.map(children, (child, i) => {
diff --git a/ui/src/index.js b/ui/src/index.js
index 7f7309c4..529aa3d7 100644
--- a/ui/src/index.js
+++ b/ui/src/index.js
@@ -6,6 +6,7 @@ module.exports = {
Column: require('./components/column'),
Container: require('./components/container'),
Input: require('./components/input'),
+ List: require('./components/list'),
Modal: require('./components/modal'),
MiniMetric: require('./components/mini-metric'),
Notificaton: require('./components/notification'),
diff --git a/ui/stories/index.js b/ui/stories/index.js
index 4147d337..8341aee6 100644
--- a/ui/stories/index.js
+++ b/ui/stories/index.js
@@ -14,6 +14,16 @@ const {
Column,
Avatar,
Input,
+ List: {
+ ListItem,
+ ListItemView,
+ ListItemTitle,
+ ListItemSubTitle,
+ ListItemDescription,
+ ListItemMeta,
+ ListItemOutlet,
+ ListItemOptions,
+ },
MiniMetric,
Modal,
Notificaton,
@@ -30,6 +40,8 @@ const {
RadioGroup
} = require('../src/');
+
+
const seed = require('./seed');
const {
selectData
@@ -471,3 +483,43 @@ storiesOf('Metrics', module)
name='Memory'
/>
));
+
+storiesOf('ListItem', module)
+ .add('default', () => (
+
+
+
+
+ Nginx 01
+ 4 instances
+ Flags
+
+
+ Metrics
+
+
+
+ …
+
+
+
+ ))
+ .add('collapsed', () => (
+
+
+
+
+ Nginx 01
+ 4 instances
+ Flags
+
+
+ Metrics
+
+
+
+ …
+
+
+
+ ));