Skip to content

Commit

Permalink
feat(SecondaryNavigation): add actions
Browse files Browse the repository at this point in the history
  • Loading branch information
zouxuoz committed Feb 18, 2019
1 parent dd56613 commit a913763
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 38 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ export default (asStory) => {
<SecondaryNavigation.Item label="Third item" />
<SecondaryNavigation.Item label="Fourth item" />
</SecondaryNavigation>
))
.add('default with actions', () => (
<SecondaryNavigation>
<SecondaryNavigation.Item label="First item" />
<SecondaryNavigation.Item label="Second item" className="active" actions={ [{ label: 'Action', onClick: () => null }] } />
<SecondaryNavigation.Item label="Third item" />
<SecondaryNavigation.Item label="Fourth item" />
</SecondaryNavigation>
));
});
};
99 changes: 88 additions & 11 deletions src/components/SecondaryNavigation/SecondaryNavigationItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,102 @@
import React from 'react';

import { Text } from '../Text';
import { Dropdown } from '../Dropdown';
import { Menu } from '../Menu';
import { Icon } from '../Icon';

import {
SecondaryNavigationItemTag,
SecondaryNavigationItemBarTag,
SecondaryNavigationItemLabelTag,
SecondaryNavigationItemActionsTag,
} from './SecondaryNavigationItem.theme';

type SecondaryNavigationItemProps = {
label?: string,
active?: boolean,
actions?: Object[] | Function,
};

type SecondaryNavigationItemState = {
openedActions: boolean,
hovered: boolean,
};

export const SecondaryNavigationItem = ({ label, ...rest }: SecondaryNavigationItemProps) => (
<SecondaryNavigationItemTag { ...rest } >
<SecondaryNavigationItemBarTag modifiers={ rest } />
<SecondaryNavigationItemLabelTag modifiers={ rest } >
<Text>
{ label }
</Text>
</SecondaryNavigationItemLabelTag>
</SecondaryNavigationItemTag>
);
class SecondaryNavigationItem extends React.PureComponent<SecondaryNavigationItemProps, SecondaryNavigationItemState> {
state = {
openedActions: false,
hovered: false,
};

openActions = () => {
this.setState({ openedActions: true });
};

closeActions = () => {
this.setState({ openedActions: false });
};

onMouseLeave = () => {
this.setState({ hovered: false });

const { active } = this.props;

if (!active) {
this.closeActions();
}
};

onMouseEnter = () => {
this.setState({ hovered: true });
};

createOnMenuItemClick = (onClick: Function) => (event: MouseEvent) => {
event.stopPropagation();

onClick(event);

this.closeActions();
};

render() {
const { label, actions, ...rest } = this.props;
const { openedActions, hovered } = this.state;

const finalActions = (typeof actions === 'function' ? actions(this.closeActions) : actions);

return (
<SecondaryNavigationItemTag { ...rest } hovered={ hovered } onMouseLeave={ this.onMouseLeave } onMouseEnter={ this.onMouseEnter } >
<SecondaryNavigationItemLabelTag tagName={ Text } modifiers={ rest } >
{ label }
</SecondaryNavigationItemLabelTag>
{
finalActions
&&
(
<SecondaryNavigationItemActionsTag>
<Dropdown isOpen={ openedActions } onCloseDropdown={ this.closeActions } onOpenDropdown={ this.openActions }>
<Dropdown.Head stopClickPropagation>
<Icon size="sm" name="Dots" color="GRAY5" />
</Dropdown.Head>
<Dropdown.Body forceRender withPortal>
<Menu>
{
finalActions.map(({ label, onClick, ...rest }) => (
<Menu.Item key={ label } onClick={ this.createOnMenuItemClick(onClick) } { ...rest }>
{ label }
</Menu.Item>
))
}
</Menu>
</Dropdown.Body>
</Dropdown>
</SecondaryNavigationItemActionsTag>
)
}
</SecondaryNavigationItemTag>
);
}
}

export { SecondaryNavigationItem };
export { theme } from './SecondaryNavigationItem.theme';
41 changes: 25 additions & 16 deletions src/components/SecondaryNavigation/SecondaryNavigationItem.theme.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
// @flow
import { createThemeTag } from '../../theme/createThemeTag';


const name = 'secondaryNavigationItem';


const [SecondaryNavigationItemTag, rootTheme] = createThemeTag(name, ({ COLORS }: *) => ({
root: {
height: '32px',
height: 28,
display: 'flex',
backgroundColor: 'inherit',
textDecoration: 'none',
userSelect: 'none',
position: 'relative',
paddingLeft: 4,
paddingRight: 20,
justifyContent: 'space-between',

'&:hover': {
backgroundColor: COLORS.WHITE,
[`&.active ${SecondaryNavigationItemActionsTag}`]: {
visibility: 'visible',
},

'&.active': {
backgroundColor: COLORS.WHITE,
paddingLeft: 0,
borderLeft: `4px solid ${COLORS.DSM.NAVIGATION_COLORS.DSM_DB_SELECTED}`,
},
},
}));


const [SecondaryNavigationItemBarTag, barTheme] = createThemeTag(`${name}Bar`, ({ COLORS }: *) => ({
root: {
width: '4px',
backgroundColor: 'inherit',
modifiers: {
hovered: {
backgroundColor: COLORS.WHITE,

'.active > &': {
backgroundColor: COLORS.DSM.NAVIGATION_COLORS.DSM_DB_SELECTED,
[`& ${SecondaryNavigationItemActionsTag}`]: {
visibility: 'visible',
},
},
},
}));
Expand All @@ -46,17 +46,26 @@ const [SecondaryNavigationItemLabelTag, labelTheme] = createThemeTag(`${name}Lab
},
}));

const [SecondaryNavigationItemActionsTag, actionsTheme] = createThemeTag(`${name}Actions`, () => ({
root: {
display: 'flex',
alignItems: 'center',
position: 'relative',
visibility: 'hidden',
},
}));

const theme = {
...rootTheme,
...barTheme,
...labelTheme,
...actionsTheme,
};


export {
theme,
SecondaryNavigationItemTag,
SecondaryNavigationItemBarTag,
SecondaryNavigationItemLabelTag,
SecondaryNavigationItemActionsTag,
};

Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,16 @@ exports[`<SecondaryNavigation /> should shallow SecondaryNavigation 1`] = `
`;

exports[`<SecondaryNavigation /> should shallow SecondaryNavigation item 1`] = `
<Boost(secondaryNavigationItem)>
<Boost(secondaryNavigationItemBar)
modifiers={Object {}}
/>
<Boost(secondaryNavigationItem)
hovered={false}
onMouseEnter={[Function]}
onMouseLeave={[Function]}
>
<Boost(secondaryNavigationItemLabel)
modifiers={Object {}}
tagName={[Function]}
>
<Text
color="DARK_GRAY1"
ellipsis={false}
weight="normal"
>
First item
</Text>
First item
</Boost(secondaryNavigationItemLabel)>
</Boost(secondaryNavigationItem)>
`;

0 comments on commit a913763

Please sign in to comment.