|
@@ -8,7 +8,7 @@ import {
|
|
|
ThemeProvider,
|
|
ThemeProvider,
|
|
|
} from '@atlaskit/navigation-next';
|
|
} from '@atlaskit/navigation-next';
|
|
|
|
|
|
|
|
-import { createSubscribedElement } from './UnstatedUtils';
|
|
|
|
|
|
|
+import { withUnstatedContainers } from './UnstatedUtils';
|
|
|
import AppContainer from '../services/AppContainer';
|
|
import AppContainer from '../services/AppContainer';
|
|
|
|
|
|
|
|
import SidebarNav from './Sidebar/SidebarNav';
|
|
import SidebarNav from './Sidebar/SidebarNav';
|
|
@@ -23,6 +23,7 @@ class Sidebar extends React.Component {
|
|
|
static propTypes = {
|
|
static propTypes = {
|
|
|
appContainer: PropTypes.instanceOf(AppContainer).isRequired,
|
|
appContainer: PropTypes.instanceOf(AppContainer).isRequired,
|
|
|
navigationUIController: PropTypes.any.isRequired,
|
|
navigationUIController: PropTypes.any.isRequired,
|
|
|
|
|
+ isDrawerModeOnInit: PropTypes.bool,
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
state = {
|
|
state = {
|
|
@@ -31,7 +32,10 @@ class Sidebar extends React.Component {
|
|
|
|
|
|
|
|
componentWillMount() {
|
|
componentWillMount() {
|
|
|
this.hackUIController();
|
|
this.hackUIController();
|
|
|
- this.initBreakpointEvents();
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ componentDidUpdate(prevProps, prevState) {
|
|
|
|
|
+ this.toggleDrawerMode(this.isDrawerMode);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -50,35 +54,75 @@ class Sidebar extends React.Component {
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- initBreakpointEvents() {
|
|
|
|
|
- const { appContainer, navigationUIController } = this.props;
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * return whether drawer mode or not
|
|
|
|
|
+ */
|
|
|
|
|
+ get isDrawerMode() {
|
|
|
|
|
+ let isDrawerMode = this.props.appContainer.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.clearNavigationTransitionTemporary(this.navigationElem);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- const mdOrAvobeHandler = (mql) => {
|
|
|
|
|
- // sm -> md
|
|
|
|
|
- if (mql.matches) {
|
|
|
|
|
- appContainer.setState({ isDrawerOpened: false });
|
|
|
|
|
- navigationUIController.enableResize();
|
|
|
|
|
|
|
+ navigationUIController.disableResize();
|
|
|
|
|
|
|
|
- // restore width
|
|
|
|
|
- if (this.sidebarWidthCached != null) {
|
|
|
|
|
- navigationUIController.setState({ productNavWidth: this.sidebarWidthCached });
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // fix width
|
|
|
|
|
+ navigationUIController.setState({ productNavWidth: sidebarDefaultWidth });
|
|
|
|
|
+ }
|
|
|
|
|
+ // Drawer --> Dock
|
|
|
|
|
+ else {
|
|
|
|
|
+ // clear transition temporary when restore collapsed sidebar
|
|
|
|
|
+ if (this.sidebarCollapsedCached) {
|
|
|
|
|
+ this.clearNavigationTransitionTemporary(this.ctxNavigationElem);
|
|
|
}
|
|
}
|
|
|
- // md -> sm
|
|
|
|
|
- else {
|
|
|
|
|
- // cache width
|
|
|
|
|
- this.sidebarWidthCached = navigationUIController.state.productNavWidth;
|
|
|
|
|
|
|
|
|
|
- appContainer.setState({ isDrawerOpened: false });
|
|
|
|
|
- navigationUIController.disableResize();
|
|
|
|
|
- navigationUIController.expand();
|
|
|
|
|
|
|
+ navigationUIController.enableResize();
|
|
|
|
|
|
|
|
- // fix width
|
|
|
|
|
- navigationUIController.setState({ productNavWidth: sidebarDefaultWidth });
|
|
|
|
|
|
|
+ // restore width
|
|
|
|
|
+ if (this.sidebarWidthCached != null) {
|
|
|
|
|
+ navigationUIController.setState({ productNavWidth: this.sidebarWidthCached });
|
|
|
}
|
|
}
|
|
|
- };
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ get navigationElem() {
|
|
|
|
|
+ return document.querySelector('div[data-testid="Navigation"]');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ get ctxNavigationElem() {
|
|
|
|
|
+ return document.querySelector('div[data-testid="ContextualNavigation"]');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ clearNavigationTransitionTemporary(elem) {
|
|
|
|
|
+ const transitionCache = elem.style.transition;
|
|
|
|
|
+
|
|
|
|
|
+ // clear
|
|
|
|
|
+ elem.style.transition = undefined;
|
|
|
|
|
|
|
|
- appContainer.addBreakpointListener('md', mdOrAvobeHandler, true);
|
|
|
|
|
|
|
+ // restore after 300ms
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ elem.style.transition = transitionCache;
|
|
|
|
|
+ }, 300);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
backdropClickedHandler = () => {
|
|
backdropClickedHandler = () => {
|
|
@@ -122,7 +166,7 @@ class Sidebar extends React.Component {
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
|
<>
|
|
<>
|
|
|
- <div className={`grw-sidebar ${isDrawerOpened ? 'open' : ''}`}>
|
|
|
|
|
|
|
+ <div className={`grw-sidebar ${this.isDrawerMode ? 'grw-sidebar-drawer' : ''} ${isDrawerOpened ? 'open' : ''}`}>
|
|
|
<ThemeProvider
|
|
<ThemeProvider
|
|
|
theme={theme => ({
|
|
theme={theme => ({
|
|
|
...theme,
|
|
...theme,
|
|
@@ -153,15 +197,35 @@ class Sidebar extends React.Component {
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-const SidebarWithNavigationUI = withNavigationUIController(Sidebar);
|
|
|
|
|
|
|
+
|
|
|
|
|
+const SidebarWithNavigationUIController = withNavigationUIController(Sidebar);
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* Wrapper component for using unstated
|
|
* Wrapper component for using unstated
|
|
|
*/
|
|
*/
|
|
|
-const SidebarWrapper = (props) => {
|
|
|
|
|
- return createSubscribedElement(SidebarWithNavigationUI, props, [AppContainer]);
|
|
|
|
|
|
|
+
|
|
|
|
|
+const SidebarWithNavigation = (props) => {
|
|
|
|
|
+ const { preferDrawerModeByUser: isDrawerModeOnInit } = props.appContainer.state;
|
|
|
|
|
+
|
|
|
|
|
+ const initUICForDrawerMode = isDrawerModeOnInit
|
|
|
|
|
+ // generate initialUIController for Drawer mode
|
|
|
|
|
+ ? {
|
|
|
|
|
+ isCollapsed: false,
|
|
|
|
|
+ isResizeDisabled: true,
|
|
|
|
|
+ productNavWidth: sidebarDefaultWidth,
|
|
|
|
|
+ }
|
|
|
|
|
+ // set undefined (should be initialized by cache)
|
|
|
|
|
+ : undefined;
|
|
|
|
|
+
|
|
|
|
|
+ return (
|
|
|
|
|
+ <NavigationProvider initialUIController={initUICForDrawerMode}>
|
|
|
|
|
+ <SidebarWithNavigationUIController {...props} isDrawerModeOnInit={isDrawerModeOnInit} />
|
|
|
|
|
+ </NavigationProvider>
|
|
|
|
|
+ );
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+SidebarWithNavigation.propTypes = {
|
|
|
|
|
+ appContainer: PropTypes.instanceOf(AppContainer).isRequired,
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-export default () => (
|
|
|
|
|
- <NavigationProvider><SidebarWrapper /></NavigationProvider>
|
|
|
|
|
-);
|
|
|
|
|
|
|
+export default withUnstatedContainers(SidebarWithNavigation, [AppContainer]);
|