Skip to content

Commit

Permalink
Allow locking of EuiNavDrawer in the expanded state (#2247)
Browse files Browse the repository at this point in the history
* Added a locked state of EuiNavDrawer
* Auto-collapses at smaller window sizes
* Collapse all when collapse button is clicked and hide extra action button on smaller screens
* Fix passing classname to extra action
* Allow passing `isLocked` as prop
* Added is `onIsLockedUpdate` callback
  • Loading branch information
cchaos authored Aug 22, 2019
1 parent e336a94 commit 59fc1a1
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 19 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## [`master`](https://github.com/elastic/eui/tree/master)

- Fixed `logoCloudEnterprise`, `logoLogging`, and `logoSecurity` SVGs in `EuiIcon` to be center aligned ([#2246](https://github.com/elastic/eui/pull/2246))
- Added locking behavior of `EuiNavDrawer` expanded state inluding the following props `isLocked`, `onIsLockedUpdate` ([#2247](https://github.com/elastic/eui/pull/2247))

## [`13.4.1`](https://github.com/elastic/eui/tree/v13.4.1)

Expand Down
14 changes: 9 additions & 5 deletions src/components/list_group/list_group_item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,15 @@ export const EuiListGroupItem: FunctionComponent<EuiListGroupItemProps> = ({
let extraActionNode;

if (extraAction) {
const { iconType, alwaysShow, ...rest } = extraAction;

const extraActionClasses = classNames('euiListGroupItem__extraAction', {
'euiListGroupItem__extraAction-alwaysShow': alwaysShow,
});
const { iconType, alwaysShow, className, ...rest } = extraAction;

const extraActionClasses = classNames(
'euiListGroupItem__extraAction',
{
'euiListGroupItem__extraAction-alwaysShow': alwaysShow,
},
className
);

extraActionNode = (
<EuiButtonIconTyped
Expand Down
28 changes: 28 additions & 0 deletions src/components/nav_drawer/_nav_drawer.scss
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,31 @@
margin-left: 0;
}
}

@include euiBreakpoint('xs', 's', 'm', 'l') {
.euiNavDrawer__expandButtonLockAction {
display: none;
}
}

@include euiBreakpoint('xl') {
.euiNavDrawer-isLocked {
+ .euiNavDrawerPage .euiNavDrawerPage__pageBody {
// Shrink the content from the left so it's no longer overlapped by the nav drawer (ALWAYS)
margin-left: $euiNavDrawerWidthExpanded !important; // sass-lint:disable-line no-important
transition: margin $euiAnimSpeedFast $euiAnimSlightResistance;
}

&.euiNavDrawer-flyoutIsExpanded {
// Instead of one collapsed and one expanded, they're now both expanded
// Double the width of expanded sidebars
width: $euiNavDrawerWidthExpanded * 2 !important; // sass-lint:disable-line no-important
}
}

// In case they unlock while the flyout is expanded,
// the nav drawer doesn't actually get collapsed until an interaction
.euiNavDrawer-isExpanded.euiNavDrawer-flyoutIsExpanded {
width: $euiNavDrawerWidthExpanded * 2 !important; // sass-lint:disable-line no-important
}
}
121 changes: 107 additions & 14 deletions src/components/nav_drawer/nav_drawer.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,64 @@ import { EuiNavDrawerGroup } from './nav_drawer_group';
import { EuiOutsideClickDetector } from '../outside_click_detector';
import { EuiI18n } from '../i18n';
import { EuiFlexItem } from '../flex';
import { throttle } from '../color_picker/utils';

export class EuiNavDrawer extends Component {
constructor(props) {
super(props);

this.state = {
isCollapsed: true,
isLocked: props.isLocked,
isCollapsed: !props.isLocked,
flyoutIsCollapsed: true,
outsideClickDisabled: true,
isManagingFocus: false,
toolTipsEnabled: true,
};
}

componentDidMount() {
if (this.props.isLocked) {
window.addEventListener('resize', this.functionToCallOnWindowResize);
}
}

componentWillUnmount() {
window.removeEventListener('resize', this.functionToCallOnWindowResize);
}

returnOnIsLockedUpdate = isLockedState => {
if (this.props.onIsLockedUpdate) {
this.props.onIsLockedUpdate(isLockedState);
}
};

functionToCallOnWindowResize = throttle(() => {
if (window.innerWidth < 1200) {
this.collapseDrawer();
this.collapseFlyout();
}
// reacts every 50ms to resize changes and always gets the final update
}, 50);

timeoutID;

sideNavLockClicked = () => {
if (this.state.isLocked) {
window.removeEventListener('resize', this.functionToCallOnWindowResize);
} else {
window.addEventListener('resize', this.functionToCallOnWindowResize);
}

this.returnOnIsLockedUpdate(!this.state.isLocked);

this.setState({
isLocked: !this.state.isLocked,
isCollapsed: false,
outsideClickDisabled: true,
});
};

toggleOpen = () => {
this.setState({
isCollapsed: !this.state.isCollapsed,
Expand All @@ -36,6 +78,16 @@ export class EuiNavDrawer extends Component {
}, 150);
};

collapseButtonClick = () => {
if (this.state.isCollapsed) {
this.expandDrawer();
} else {
this.collapseDrawer();
}

this.collapseFlyout();
};

expandDrawer = () => {
this.setState({
isCollapsed: false,
Expand All @@ -54,12 +106,18 @@ export class EuiNavDrawer extends Component {
isCollapsed: true,
outsideClickDisabled: this.state.flyoutIsCollapsed ? true : false,
toolTipsEnabled: true,
isLocked: false,
});

this.returnOnIsLockedUpdate(false);

// Scrolls the menu and flyout back to top when the nav drawer collapses
setTimeout(() => {
document.getElementById('navDrawerMenu').scrollTop = 0;
}, 50);

// In case it was locked before, remove the window resize listener
window.removeEventListener('resize', this.functionToCallOnWindowResize);
};

manageFocus = () => {
Expand Down Expand Up @@ -103,7 +161,7 @@ export class EuiNavDrawer extends Component {
flyoutIsCollapsed: false,
navFlyoutTitle: title,
navFlyoutContent: content,
isCollapsed: true,
isCollapsed: this.state.isLocked ? false : true,
toolTipsEnabled: false,
outsideClickDisabled: false,
});
Expand All @@ -115,12 +173,12 @@ export class EuiNavDrawer extends Component {
flyoutIsCollapsed: true,
navFlyoutTitle: null,
navFlyoutContent: null,
toolTipsEnabled: true,
toolTipsEnabled: this.state.isLocked ? false : true,
});
};

closeBoth = () => {
this.collapseDrawer();
if (!this.state.isLocked) this.collapseDrawer();
this.collapseFlyout();
};

Expand Down Expand Up @@ -150,6 +208,9 @@ export class EuiNavDrawer extends Component {
className,
showExpandButton,
showToolTips,
isCollapsed,
isLocked,
onIsLockedUpdate,
...rest
} = this.props;

Expand All @@ -158,6 +219,7 @@ export class EuiNavDrawer extends Component {
{
'euiNavDrawer-isCollapsed': this.state.isCollapsed,
'euiNavDrawer-isExpanded': !this.state.isCollapsed,
'euiNavDrawer-isLocked': this.state.isLocked,
'euiNavDrawer-flyoutIsCollapsed': this.state.flyoutIsCollapsed,
'euiNavDrawer-flyoutIsExpanded': !this.state.flyoutIsCollapsed,
},
Expand All @@ -172,22 +234,43 @@ export class EuiNavDrawer extends Component {
tokens={[
'euiNavDrawer.sideNavCollapse',
'euiNavDrawer.sideNavExpand',
'euiNavDrawer.sideNavLockAriaLabel',
'euiNavDrawer.sideNavLockExpanded',
'euiNavDrawer.sideNavLockCollapsed',
]}
defaults={['Collapse', 'Expand']}>
{([sideNavCollapse, sideNavExpand]) => (
defaults={[
'Collapse',
'Expand',
'Dock navigation',
'Navigation is docked',
'Navigation is undocked',
]}>
{([
sideNavCollapse,
sideNavExpand,
sideNavLockAriaLabel,
sideNavLockExpanded,
sideNavLockCollapsed,
]) => (
<EuiListGroupItem
label={this.state.isCollapsed ? sideNavExpand : sideNavCollapse}
iconType={this.state.isCollapsed ? 'menuRight' : 'menuLeft'}
size="s"
showToolTip={this.state.isCollapsed}
onClick={
this.state.isCollapsed
? () => {
this.expandDrawer();
this.collapseFlyout();
}
: () => this.collapseDrawer()
}
extraAction={{
className: 'euiNavDrawer__expandButtonLockAction',
color: 'text',
onClick: this.sideNavLockClicked,
iconType: this.state.isLocked ? 'lock' : 'lockOpen',
iconSize: 's',
'aria-label': sideNavLockAriaLabel,
title: this.state.isLocked
? sideNavLockCollapsed
: sideNavLockExpanded,
'aria-checked': this.state.isLocked ? true : false,
role: 'switch',
}}
onClick={this.collapseButtonClick}
data-test-subj={
this.state.isCollapsed
? 'navDrawerExpandButton-isCollapsed'
Expand Down Expand Up @@ -273,6 +356,16 @@ EuiNavDrawer.propTypes = {
* Display tooltips on side nav items
*/
showToolTips: PropTypes.bool,

/**
* Keep drawer locked open by default
*/
isLocked: PropTypes.bool,

/**
* Returns the current state of isLocked
*/
onIsLockedUpdate: PropTypes.func,
};

EuiNavDrawer.defaultProps = {
Expand Down

0 comments on commit 59fc1a1

Please sign in to comment.