@mongodb-js/mongodb-ui-components
Version:
A collection of frequently used functional UI components found on mongodb properties
138 lines (121 loc) • 4.08 kB
JavaScript
'use strict';
import {h, Component} from 'preact';
import TopPanel from './js/nav-top';
import MiddlePanel from './js/nav-middle';
import BottomPanel from './js/nav-bottom';
import Background from './js/background';
export default class Nav extends Component {
constructor(props) {
super(props);
this.state = {
isMobile: this.props.isMobile || false,
isOpen: false,
activeSection: -1,
breakpoint: 895
};
this.env = this.props.environment || 'com';
this.toggle = this.toggle.bind(this);
this.setActiveSection = this.setActiveSection.bind(this);
this.onResize = this.onResize.bind(this);
this.setNavOffset = this.setNavOffset.bind(this);
this.resetNav = this.resetNav.bind(this);
}
componentDidMount() {
this.onResize();
window.addEventListener('resize', this.onResize);
window.addEventListener('scroll', this.setNavOffset);
this.navStyle = document.querySelector('.m-nav').style;
this.navBGStyle = document.querySelector('.m-nav-bg').style;
}
onResize() {
const { isMobile, breakpoint } = this.state;
const { innerWidth } = window;
if (isMobile && innerWidth > breakpoint) {
this.setState({ isMobile: false, isOpen: false, activeSection: -1 }, () => {
this.resetNav();
});
document.body.classList.remove('no-scroll');
} else if (!isMobile && innerWidth <= breakpoint) {
this.setState({ isMobile: true, activeSection: -1 }, () => {
this.setNavOffset();
});
}
}
setNavOffset() {
if (!this.props.isTopNavHidden && !this.props.disableMobileNavOffset && this.state.isMobile) {
if (window.pageYOffset >= 45) {
this.navStyle.position = 'fixed';
this.navStyle.top = '-45px';
this.navBGStyle.top = '-45px';
this.navBGStyle.height = 'calc(100% - 50px)';
} else {
this.navStyle.position = 'absolute';
this.navStyle.top = '0';
this.navBGStyle.top = `-${window.pageYOffset}px`;
this.navBGStyle.height = `calc(100% - ${95 - window.pageYOffset}px)`;
}
}
}
resetNav() {
if (!this.props.isTopNavHidden && !this.props.disableMobileNavOffset) {
this.navStyle.position = 'fixed';
this.navStyle.top = '0px';
this.navBGStyle.top = '0px';
this.navBGStyle.height = '600px';
}
}
setActiveSection(activeSection) {
this.setState({
activeSection: activeSection,
isOpen: activeSection > -1
});
}
toggle() {
const isOpen = !this.state.isOpen;
if (this.state.isMobile) {
document.body.classList.toggle('no-scroll', isOpen);
}
this.setState({ isOpen });
}
render() {
const active = this.state.activeSection;
const mobile = this.state.isMobile;
return h(
'nav',
{
style: this.props.isTopNavHidden ? { top: '-45px' } : null,
className: 'm-nav m-nav-flex-y' },
h(TopPanel, {
downloadUrl: this.props.downloadUrl,
downloadJmpValue: this.props.downloadJmpValue,
includeSearch: this.props.includeSearch,
host: this.env === 'com' ? '' : 'https://www.mongodb.com',
sections: this.props.topSections,
searchUrl: this.props.searchUrl,
contactUrl: this.props.contactUrl }),
h(MiddlePanel, {
activeSection: active,
isMobile: mobile,
logoUrl: this.props.logoUrl,
tagline: this.props.tagline,
logoLink: this.props.logoLink,
sections: this.props.sections,
toggle: this.toggle,
setActiveSection: this.setActiveSection }),
h(
Background,
{
isMobile: mobile,
setActiveSection: this.setActiveSection,
isOpaque: this.state.isOpen || active !== -1 || this.props.isOpaque,
isOpen: this.state.isOpen,
isTopNavHidden: this.props.isTopNavHidden },
h(BottomPanel, {
isMobile: mobile,
activeSection: active,
midSections: this.props.sections,
sections: this.props.subsections })
)
);
}
}