Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow locking of EuiNavDrawer in the expanded state #2247

Merged
merged 16 commits into from
Aug 22, 2019
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## [`master`](https://github.com/elastic/eui/tree/master)

No public interface changes since `13.4.1`.
- 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
}
}
118 changes: 104 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 = () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to remove the resize event listener in this function, also. Otherwise window resizing continues

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,40 @@ export class EuiNavDrawer extends Component {
tokens={[
'euiNavDrawer.sideNavCollapse',
'euiNavDrawer.sideNavExpand',
'euiNavDrawer.sideNavLockExpanded',
'euiNavDrawer.sideNavLockCollapsed',
]}
defaults={['Collapse', 'Expand']}>
{([sideNavCollapse, sideNavExpand]) => (
defaults={[
'Collapse',
'Expand',
'Lock navigation open',
'Unlock navigation',
]}>
{([
sideNavCollapse,
sideNavExpand,
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 ? 'lockOpen' : 'lock',
iconSize: 's',
'aria-label': sideNavLockExpanded,
title: this.state.isLocked
? sideNavLockCollapsed
: sideNavLockExpanded,
'aria-checked': this.state.isLocked ? true : false,
role: 'switch',
cchaos marked this conversation as resolved.
Show resolved Hide resolved
}}
onClick={this.collapseButtonClick}
data-test-subj={
this.state.isCollapsed
? 'navDrawerExpandButton-isCollapsed'
Expand Down Expand Up @@ -273,6 +353,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