Skip to content

Commit

Permalink
Merge pull request #4 from cchaos/rk/side-nav-2/hovers
Browse files Browse the repository at this point in the history
Simplify flyout children logic by adding `EuiNavDrawerGroup`
  • Loading branch information
Ryan Keairns authored Mar 11, 2019
2 parents 8a9d393 + 5a215bc commit 2234d30
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 92 deletions.
10 changes: 5 additions & 5 deletions src-docs/src/views/nav_drawer/nav_drawer.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import {
EuiHeaderLogo,
EuiIcon,
EuiTitle,
EuiNavDrawerGroup,
EuiNavDrawer,
EuiListGroup,
EuiHorizontalRule,
EuiShowFor,
EuiFocusTrap,
Expand Down Expand Up @@ -493,13 +493,13 @@ export default class extends Component {
</EuiHeaderSection>
</EuiHeader>
<EuiNavDrawer ref={this.setNavDrawerRef}>
<EuiListGroup listItems={this.topLinks} />
<EuiNavDrawerGroup listItems={this.topLinks} />
<EuiHorizontalRule margin="none" />
<EuiListGroup listItems={this.exploreLinks} />
<EuiNavDrawerGroup listItems={this.exploreLinks} />
<EuiHorizontalRule margin="none" />
<EuiListGroup listItems={this.solutionsLinks} />
<EuiNavDrawerGroup listItems={this.solutionsLinks} />
<EuiHorizontalRule margin="none" />
<EuiListGroup listItems={this.adminLinks} />
<EuiNavDrawerGroup listItems={this.adminLinks}/>
</EuiNavDrawer>
<EuiPage className="euiNavDrawerPage">
<EuiPageBody className="euiNavDrawerPage__pageBody">
Expand Down
1 change: 1 addition & 0 deletions src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ export {

export {
EuiNavDrawer,
EuiNavDrawerGroup,
EuiNavDrawerFlyout,
} from './nav_drawer';

Expand Down
4 changes: 4 additions & 0 deletions src/components/nav_drawer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ export {
EuiNavDrawer,
} from './nav_drawer';

export {
EuiNavDrawerGroup,
} from './nav_drawer_group';

export {
EuiNavDrawerFlyout,
} from './nav_drawer_flyout';
95 changes: 8 additions & 87 deletions src/components/nav_drawer/nav_drawer.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,93 +180,14 @@ export class EuiNavDrawer extends Component {
let modifiedChildren = children;

// 1. Loop through the EuiNavDrawer children (EuiListGroup, EuiHorizontalRules, etc)
modifiedChildren = React.Children.map(this.props.children, (child, childIndex) => {

// 2a. Check if child is an EuiListGroup (i.e. not an EuiHorizontalRule)
if (child.type.name === 'EuiListGroup') {

// 3a. Loop through list items passed as an array on EuiListGroup
if (typeof child.props.listItems !== 'undefined') {
const listItemArray = child.props.listItems;
const modifiedListItems = listItemArray.map((item) => {
// 4. If there is a flyoutMenu prop, then add an onClick prop
if (item.flyoutMenu) {
const { flyoutMenu, ...itemProps } = item;
return {
onClick: () => this.expandFlyout(flyoutMenu.listItems, flyoutMenu.title),
...itemProps
};
}
return item;
});
child = ({ ...child, ...{
props: ({ ...child.props, ...{ listItems: modifiedListItems } })
} });
}

// 3b. Loop through list itmes passed as separate EuiListGroupItem components
if (typeof child.props.children !== 'undefined') {
const listGroupItems = child.props.children;

// 4. If there is a flyoutMenu prop, then add an onClick prop
// If only one child, then there is no index; props is top level
if (listGroupItems.props) {
const item = React.cloneElement(listGroupItems, {
onClick: listGroupItems.props.flyoutMenu ?
() => this.expandFlyout(
listGroupItems.props.flyoutMenu.listItems,
listGroupItems.props.flyoutMenu.title
)
: null,
});

// Remove `flyoutMenu` so it doesn't get passed to the DOM
const {
flyoutMenu, // eslint-disable-line no-unused-vars
...itemProps
} = item.props;

child = React.cloneElement(child, {
key: childIndex,
children: ({ ...item, ...{ props: { ...itemProps } } })
});
// If more than one child, then there is an index
} else {
child = React.cloneElement(child, {
key: childIndex,
children: Object.keys(listGroupItems).map((key, itemIndex) => {
const item = React.cloneElement(listGroupItems[key], {
key: itemIndex,
onClick: listGroupItems[itemIndex].props.flyoutMenu ?
() => this.expandFlyout(
listGroupItems[itemIndex].props.flyoutMenu.listItems,
listGroupItems[itemIndex].props.flyoutMenu.title
)
: null,
});

// Remove `flyoutMenu` so it doesn't get passed to the DOM
const {
flyoutMenu, // eslint-disable-line no-unused-vars
...itemProps
} = item.props;

return ({ ...item, ...{ props: { ...itemProps } } });
})
});
}
}

// 5. If showToolTips passed and currently enabled, add showToolTips prop to EuiListGroup
if (this.state.toolTipsEnabled && showToolTips) {
return React.cloneElement(child, {
showToolTips: true
});
} else {
return child;
}

// 2b. Child is not an EuiListGroup, so just return it as-is
modifiedChildren = React.Children.map(this.props.children, child => {
// 2. Check if child is an EuiNavDrawerGroup and if it does have a flyout, add the expand function
if (child.type.name === 'EuiNavDrawerGroup') {
const item = React.cloneElement(child, {
flyoutMenuButtonClick: this.expandFlyout,
showToolTips: this.state.toolTipsEnabled && showToolTips,
});
return item;
} else {
return child;
}
Expand Down
48 changes: 48 additions & 0 deletions src/components/nav_drawer/nav_drawer_group.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import { EuiListGroup } from '../list_group/list_group';

export const EuiNavDrawerGroup = ({ className, listItems, flyoutMenuButtonClick, ...rest }) => {
const classes = classNames(
'euiNavDrawerGroup',
className
);

// Create handlers if flyoutMenu exists
const newListItems = listItems.map((item) => {
// If the flyout menu exists, pass back the list of times and the title with the onClick handler of the item
if (item.flyoutMenu && flyoutMenuButtonClick) {
const items = [...item.flyoutMenu.listItems];
const title = `${item.flyoutMenu.title}`;
item.onClick = () => flyoutMenuButtonClick(items, title);
}

// Then remove the flyoutMenu key
delete item.flyoutMenu;

// And return the item
return item;
});


return (
<EuiListGroup className={classes} listItems={newListItems} {...rest} />
);
};

EuiNavDrawerGroup.propTypes = {
listItems: PropTypes.arrayOf(PropTypes.shape({
...EuiListGroup.propTypes.listItems[0],
flyoutMenu: PropTypes.shape({
title: PropTypes.string.isRequired,
listItems: EuiListGroup.propTypes.listItems.isRequired,
}),
})).isRequired,
/**
* While not normally required, it is required to pass a function for handling
* of the flyout menu button click
*/
flyoutMenuButtonClick: PropTypes.func,
};

0 comments on commit 2234d30

Please sign in to comment.