import React from 'react';
import PropTypes from 'prop-types';
import {
withNavigationUIController,
LayoutManager,
NavigationProvider,
ThemeProvider,
} from '@atlaskit/navigation-next';
import { withUnstatedContainers } from './UnstatedUtils';
import AppContainer from '../services/AppContainer';
import NavigationContainer from '../services/NavigationContainer';
import DrawerToggler from './Navbar/DrawerToggler';
import SidebarNav from './Sidebar/SidebarNav';
import SidebarContents from './Sidebar/SidebarContents';
import StickyStretchableScroller from './StickyStretchableScroller';
const sidebarDefaultWidth = 320;
class Sidebar extends React.Component {
static propTypes = {
appContainer: PropTypes.instanceOf(AppContainer).isRequired,
navigationContainer: PropTypes.instanceOf(NavigationContainer).isRequired,
navigationUIController: PropTypes.any.isRequired,
isDrawerModeOnInit: PropTypes.bool,
};
componentWillMount() {
this.hackUIController();
}
componentDidUpdate(prevProps, prevState) {
this.toggleDrawerMode(this.isDrawerMode);
}
/**
* hack and override UIController.storeState
*
* Since UIController is an unstated container, setState() in storeState method should be awaited before writing to cache.
*/
hackUIController() {
const { navigationUIController } = this.props;
// see: @atlaskit/navigation-next/dist/esm/ui-controller/UIController.js
const orgStoreState = navigationUIController.storeState;
navigationUIController.storeState = async(state) => {
await navigationUIController.setState(state);
orgStoreState(state);
};
}
/**
* return whether drawer mode or not
*/
get isDrawerMode() {
let isDrawerMode = this.props.navigationContainer.state.isDrawerMode;
if (isDrawerMode == null) {
isDrawerMode = this.props.isDrawerModeOnInit;
}
return isDrawerMode;
}
toggleDrawerMode(bool) {
const { navigationUIController } = this.props;
const isStateModified = navigationUIController.state.isResizeDisabled !== bool;
if (!isStateModified) {
return;
}
// Drawer <-- Dock
if (bool) {
// cache state
this.sidebarCollapsedCached = navigationUIController.state.isCollapsed;
this.sidebarWidthCached = navigationUIController.state.productNavWidth;
// clear transition temporary
if (this.sidebarCollapsedCached) {
this.addCssClassTemporary('grw-sidebar-supress-transitions-to-drawer');
}
navigationUIController.disableResize();
// fix width
navigationUIController.setState({ productNavWidth: sidebarDefaultWidth });
}
// Drawer --> Dock
else {
// clear transition temporary
if (this.sidebarCollapsedCached) {
this.addCssClassTemporary('grw-sidebar-supress-transitions-to-dock');
}
navigationUIController.enableResize();
// restore width
if (this.sidebarWidthCached != null) {
navigationUIController.setState({ productNavWidth: this.sidebarWidthCached });
}
}
}
get sidebarElem() {
return document.querySelector('.grw-sidebar');
}
addCssClassTemporary(className) {
// clear
this.sidebarElem.classList.add(className);
// restore after 300ms
setTimeout(() => {
this.sidebarElem.classList.remove(className);
}, 300);
}
backdropClickedHandler = () => {
const { navigationContainer } = this.props;
navigationContainer.toggleDrawer();
}
itemSelectedHandler = (contentsId) => {
const { navigationContainer, navigationUIController } = this.props;
const { sidebarContentsId } = navigationContainer.state;
// already selected
if (sidebarContentsId === contentsId) {
navigationUIController.toggleCollapse();
}
// switch and expand
else {
navigationUIController.expand();
}
}
calcViewHeight() {
const containerElem = document.querySelector('#grw-sidebar-content-container');
return window.innerHeight - containerElem.getBoundingClientRect().top;
}
renderGlobalNavigation = () => (