fix(ui): top nav menu behavior on guide
This commit is contained in:
parent
6bbe152f34
commit
4994cd828e
@ -41,7 +41,7 @@ export const wrapPageElement = ({ element, props }) => {
|
||||
}
|
||||
if (/^\/guide(\/.*)*/.test(pathname)) {
|
||||
return (
|
||||
<DefaultLayout onGuide={true}>
|
||||
<DefaultLayout disableMenuButtonBehavior={true} mediaBreakpoint='991px'>
|
||||
<GuideLayout>{element}</GuideLayout>
|
||||
</DefaultLayout>
|
||||
);
|
||||
|
@ -1,5 +1,4 @@
|
||||
.signup-btn.btn,
|
||||
#top-right-nav .signup-btn.btn {
|
||||
.signup-btn {
|
||||
background-color: #ffac33;
|
||||
background-image: linear-gradient(#ffcc4d, #ffac33);
|
||||
-ms-filter: 'progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffcc4d, endColorstr=#ffac33, GradientType=0)';
|
||||
@ -10,18 +9,14 @@
|
||||
}
|
||||
.signup-btn:hover,
|
||||
.signup-btn:focus,
|
||||
.signup-btn:active:hover,
|
||||
#top-right-nav .signup-btn:hover,
|
||||
#top-right-nav .signup-btn:focus,
|
||||
#top-right-nav .signup-btn:active:hover {
|
||||
.signup-btn:active:hover {
|
||||
background-color: #e99110;
|
||||
background-image: linear-gradient(#ffcc4d, #e99110);
|
||||
-ms-filter: 'progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffcc4d, endColorstr=#e99110, GradientType=0)';
|
||||
border-color: #ec8b11;
|
||||
color: #292f33 !important;
|
||||
}
|
||||
.signup-btn:active,
|
||||
#top-right-nav .signup-btn:active {
|
||||
.signup-btn:active {
|
||||
background-color: #f2a330;
|
||||
background-image: none;
|
||||
box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.3);
|
||||
|
@ -41,41 +41,22 @@ header {
|
||||
background-color: #006400;
|
||||
}
|
||||
|
||||
#top-right-nav a,
|
||||
#top-right-nav img {
|
||||
max-height: var(--header-height);
|
||||
}
|
||||
|
||||
#top-right-nav > li > a {
|
||||
padding: 8px 15px;
|
||||
}
|
||||
|
||||
#top-right-nav li {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#top-right-nav a {
|
||||
.top-right-nav-link {
|
||||
max-height: var(--header-height);
|
||||
color: #fff;
|
||||
font-size: 18px;
|
||||
padding: 8px 15px;
|
||||
}
|
||||
|
||||
#top-right-nav a:hover,
|
||||
#top-right-nav a:focus {
|
||||
.top-right-nav-link:hover,
|
||||
.top-right-nav-link:focus,
|
||||
.top-right-nav-link:active {
|
||||
background-color: #fff;
|
||||
color: #006400;
|
||||
}
|
||||
|
||||
#top-right-nav li.user-state-link,
|
||||
#top-right-nav li.user-state-link:hover,
|
||||
#top-right-nav li.user-state-link:focus,
|
||||
#top-right-nav li.user-state-link > a,
|
||||
#top-right-nav li.user-state-link > a:hover,
|
||||
#top-right-nav li.user-state-link > a:focus {
|
||||
background-color: #006400;
|
||||
}
|
||||
|
||||
#top-right-nav a:hover,
|
||||
#top-right-nav a:focus {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@ -175,8 +156,21 @@ header {
|
||||
}
|
||||
|
||||
#top-nav .menu-button {
|
||||
display: none;
|
||||
color: white;
|
||||
background-color: transparent;
|
||||
margin: 0 20px 0 12px;
|
||||
padding: 2px 14px;
|
||||
border: 1px solid #fff;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
#top-nav .menu-button-open {
|
||||
background: white;
|
||||
color: #006400;
|
||||
}
|
||||
|
||||
#top-right-nav .signup-btn {
|
||||
margin: 0 15px;
|
||||
}
|
||||
|
||||
@media (max-width: 734px) {
|
||||
@ -184,28 +178,9 @@ header {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#top-nav .menu-button {
|
||||
display: block;
|
||||
margin: 0 20px 0 12px;
|
||||
padding: 2px 14px;
|
||||
border: 1px solid #fff;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.opened #top-right-nav {
|
||||
top: var(--header-height);
|
||||
}
|
||||
|
||||
.opened #top-nav .menu-button {
|
||||
background: white;
|
||||
color: #006400;
|
||||
}
|
||||
|
||||
#top-right-nav {
|
||||
position: absolute;
|
||||
top: -300px;
|
||||
top: var(--header-height);
|
||||
flex-direction: column;
|
||||
width: 100vw;
|
||||
height: min-content;
|
||||
@ -233,41 +208,3 @@ header {
|
||||
top: 2.4em;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 735px) and (max-width: 991px) {
|
||||
.onGuide #top-nav {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.onGuide #top-nav .menu-button {
|
||||
display: block;
|
||||
margin: 0 20px 0 12px;
|
||||
padding: 2px 14px;
|
||||
border: 1px solid #fff;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.onGuide #top-right-nav {
|
||||
top: var(--header-height);
|
||||
}
|
||||
|
||||
.opened #top-nav .menu-button {
|
||||
background: white;
|
||||
color: #006400;
|
||||
}
|
||||
|
||||
.onGuide #top-right-nav {
|
||||
position: absolute;
|
||||
top: -300px;
|
||||
flex-direction: column;
|
||||
width: 100vw;
|
||||
height: min-content;
|
||||
min-height: 160px;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.onGuide #top-nav img {
|
||||
margin: 0 0 0 10px;
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ import { Link } from '../helpers';
|
||||
import './header.css';
|
||||
|
||||
import {
|
||||
toggleDisplaySideNav,
|
||||
toggleDisplayMenu,
|
||||
displayMenuSelector
|
||||
} from '../layouts/components/guide/redux';
|
||||
@ -26,14 +25,14 @@ const mapStateToProps = createSelector(
|
||||
);
|
||||
|
||||
const mapDispatchToProps = dispatch =>
|
||||
bindActionCreators({ toggleDisplaySideNav, toggleDisplayMenu }, dispatch);
|
||||
bindActionCreators({ toggleDisplayMenu }, dispatch);
|
||||
|
||||
const propTypes = {
|
||||
disableMenuButtonBehavior: PropTypes.bool,
|
||||
disableSettings: PropTypes.bool,
|
||||
displayMenu: PropTypes.bool,
|
||||
onGuide: PropTypes.bool,
|
||||
toggleDisplayMenu: PropTypes.func,
|
||||
toggleDisplaySideNav: PropTypes.func
|
||||
mediaBreakpoint: PropTypes.string.isRequired,
|
||||
toggleDisplayMenu: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
class Header extends Component {
|
||||
@ -50,97 +49,85 @@ class Header extends Component {
|
||||
document.removeEventListener('click', this.handleClickOutside);
|
||||
}
|
||||
|
||||
toggleDisplayMenuLogic = () => {
|
||||
if (this.props.onGuide) {
|
||||
this.props.toggleDisplaySideNav();
|
||||
} else {
|
||||
this.props.toggleDisplayMenu();
|
||||
}
|
||||
};
|
||||
|
||||
handleClickOutside = event => {
|
||||
if (
|
||||
!this.props.disableMenuButtonBehavior &&
|
||||
this.props.displayMenu &&
|
||||
!this.menuButtonRef.current.contains(event.target) &&
|
||||
!this.props.onGuide
|
||||
this.menuButtonRef.current &&
|
||||
!this.menuButtonRef.current.contains(event.target)
|
||||
) {
|
||||
this.toggleDisplayMenuLogic();
|
||||
this.props.toggleDisplayMenu();
|
||||
}
|
||||
};
|
||||
|
||||
handleMediaChange = matches => {
|
||||
if (!matches && this.props.displayMenu) {
|
||||
this.toggleDisplayMenuLogic();
|
||||
this.props.toggleDisplayMenu();
|
||||
}
|
||||
};
|
||||
|
||||
renderClassNames = (displayMenu, onGuide) => {
|
||||
if (displayMenu && onGuide) {
|
||||
return 'opened onGuide';
|
||||
} else if (displayMenu) {
|
||||
return 'opened';
|
||||
} else if (onGuide) {
|
||||
return 'onGuide';
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
disableMenuButtonBehavior,
|
||||
disableSettings,
|
||||
onGuide,
|
||||
displayMenu,
|
||||
mediaBreakpoint,
|
||||
toggleDisplayMenu
|
||||
} = this.props;
|
||||
return (
|
||||
<header className={this.renderClassNames(displayMenu, onGuide)}>
|
||||
<header>
|
||||
<nav id='top-nav'>
|
||||
<Link className='home-link' to='/'>
|
||||
<NavLogo />
|
||||
</Link>
|
||||
{disableSettings ? null : <FCCSearch />}
|
||||
<Media query='(max-width: 991px)'>
|
||||
{matches =>
|
||||
matches && onGuide && displayMenu ? null : (
|
||||
<ul id='top-right-nav'>
|
||||
<li onClick={toggleDisplayMenu}>
|
||||
<Link to='/learn'>Learn</Link>
|
||||
<Media maxWidth={mediaBreakpoint} onChange={this.handleMediaChange}>
|
||||
{matches => [
|
||||
matches && (
|
||||
<button
|
||||
aria-expanded={displayMenu}
|
||||
className={
|
||||
'menu-button' + (displayMenu ? ' menu-button-open' : '')
|
||||
}
|
||||
key='menu-button'
|
||||
onClick={toggleDisplayMenu}
|
||||
ref={this.menuButtonRef}
|
||||
>
|
||||
Menu
|
||||
</button>
|
||||
),
|
||||
(!matches || (displayMenu && !disableMenuButtonBehavior)) && (
|
||||
<ul id='top-right-nav' key='top-right-nav'>
|
||||
<li>
|
||||
<Link className='top-right-nav-link' to='/learn'>
|
||||
Learn
|
||||
</Link>
|
||||
</li>
|
||||
<li onClick={toggleDisplayMenu}>
|
||||
<Link external={true} to='/forum'>
|
||||
<li>
|
||||
<Link
|
||||
className='top-right-nav-link'
|
||||
external={true}
|
||||
to='/forum'
|
||||
>
|
||||
Forum
|
||||
</Link>
|
||||
</li>
|
||||
<li onClick={toggleDisplayMenu}>
|
||||
<Link external={true} to='/news'>
|
||||
<li>
|
||||
<Link
|
||||
className='top-right-nav-link'
|
||||
external={true}
|
||||
to='/news'
|
||||
>
|
||||
News
|
||||
</Link>
|
||||
</li>
|
||||
<li className='user-state-link' onClick={toggleDisplayMenu}>
|
||||
<li>
|
||||
<UserState disableSettings={disableSettings} />
|
||||
</li>
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
]}
|
||||
</Media>
|
||||
<span
|
||||
className='menu-button'
|
||||
onClick={this.toggleDisplayMenuLogic}
|
||||
ref={this.menuButtonRef}
|
||||
>
|
||||
Menu
|
||||
</span>
|
||||
{onGuide ? (
|
||||
<Media
|
||||
onChange={this.handleMediaChange}
|
||||
query='(max-width: 991px)'
|
||||
/>
|
||||
) : (
|
||||
<Media
|
||||
onChange={this.handleMediaChange}
|
||||
query='(max-width: 734px)'
|
||||
/>
|
||||
)}
|
||||
</nav>
|
||||
</header>
|
||||
);
|
||||
@ -148,6 +135,9 @@ class Header extends Component {
|
||||
}
|
||||
|
||||
Header.propTypes = propTypes;
|
||||
Header.defaultProps = {
|
||||
mediaBreakpoint: '734px'
|
||||
};
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
|
@ -56,6 +56,7 @@ const metaKeywords = [
|
||||
|
||||
const propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
disableMenuButtonBehavior: PropTypes.bool,
|
||||
disableSettings: PropTypes.bool,
|
||||
fetchUser: PropTypes.func.isRequired,
|
||||
flashMessages: PropTypes.arrayOf(
|
||||
@ -69,7 +70,7 @@ const propTypes = {
|
||||
isOnline: PropTypes.bool.isRequired,
|
||||
isSignedIn: PropTypes.bool,
|
||||
landingPage: PropTypes.bool,
|
||||
onGuide: PropTypes.bool,
|
||||
mediaBreakpoint: PropTypes.string,
|
||||
onlineStatusChange: PropTypes.func.isRequired,
|
||||
removeFlashMessage: PropTypes.func.isRequired,
|
||||
showFooter: PropTypes.bool
|
||||
@ -141,7 +142,8 @@ class DefaultLayout extends Component {
|
||||
removeFlashMessage,
|
||||
landingPage,
|
||||
showFooter = true,
|
||||
onGuide = false,
|
||||
mediaBreakpoint,
|
||||
disableMenuButtonBehavior,
|
||||
isOnline,
|
||||
isSignedIn
|
||||
} = this.props;
|
||||
@ -160,7 +162,11 @@ class DefaultLayout extends Component {
|
||||
>
|
||||
<style>{fontawesome.dom.css()}</style>
|
||||
</Helmet>
|
||||
<Header disableSettings={disableSettings} onGuide={onGuide} />
|
||||
<Header
|
||||
disableMenuButtonBehavior={disableMenuButtonBehavior}
|
||||
disableSettings={disableSettings}
|
||||
mediaBreakpoint={mediaBreakpoint}
|
||||
/>
|
||||
<div className={`default-layout ${landingPage ? 'landing-page' : ''}`}>
|
||||
<OfflineWarning isOnline={isOnline} isSignedIn={isSignedIn} />
|
||||
{hasMessages ? (
|
||||
|
@ -14,8 +14,7 @@ import './guide.css';
|
||||
|
||||
import {
|
||||
toggleExpandedState,
|
||||
toggleDisplaySideNav,
|
||||
displaySideNavSelector,
|
||||
toggleDisplayMenu,
|
||||
displayMenuSelector,
|
||||
expandedStateSelector
|
||||
} from './components/guide/redux';
|
||||
@ -37,48 +36,37 @@ const propTypes = {
|
||||
})
|
||||
}),
|
||||
displayMenu: PropTypes.bool,
|
||||
displaySideNav: PropTypes.bool,
|
||||
expandedState: PropTypes.object,
|
||||
location: PropTypes.object,
|
||||
toggleDisplaySideNav: PropTypes.func,
|
||||
toggleDisplayMenu: PropTypes.func,
|
||||
toggleExpandedState: PropTypes.func
|
||||
};
|
||||
|
||||
const mapStateToProps = createSelector(
|
||||
displaySideNavSelector,
|
||||
displayMenuSelector,
|
||||
expandedStateSelector,
|
||||
(displaySideNav, displayMenu, expandedState) => ({
|
||||
displaySideNav,
|
||||
(displayMenu, expandedState) => ({
|
||||
displayMenu,
|
||||
expandedState
|
||||
})
|
||||
);
|
||||
|
||||
const mapDispatchToProps = dispatch =>
|
||||
bindActionCreators({ toggleExpandedState, toggleDisplaySideNav }, dispatch);
|
||||
bindActionCreators({ toggleExpandedState, toggleDisplayMenu }, dispatch);
|
||||
|
||||
class GuideLayout extends React.Component {
|
||||
getContentRef = ref => (this.contentRef = ref);
|
||||
|
||||
handleNavigation = () => {
|
||||
this.contentRef.scrollTop = 0;
|
||||
this.contentRef.focus();
|
||||
handleNavigation = () => {};
|
||||
|
||||
hideSideNav = () => {
|
||||
if (this.props.displayMenu) {
|
||||
this.props.toggleDisplayMenu();
|
||||
}
|
||||
};
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.props.displayMenu) {
|
||||
this.props.toggleDisplaySideNav();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
let {
|
||||
displaySideNav,
|
||||
expandedState,
|
||||
toggleExpandedState,
|
||||
toggleDisplaySideNav
|
||||
} = this.props;
|
||||
const { expandedState, toggleExpandedState, displayMenu } = this.props;
|
||||
return (
|
||||
<StaticQuery
|
||||
query={graphql`
|
||||
@ -105,24 +93,16 @@ class GuideLayout extends React.Component {
|
||||
<Spacer size={1} />
|
||||
<Grid className='guide-container'>
|
||||
<Row>
|
||||
<Col
|
||||
md={4}
|
||||
smHidden={!displaySideNav}
|
||||
xsHidden={!displaySideNav}
|
||||
>
|
||||
<Col md={4} smHidden={!displayMenu} xsHidden={!displayMenu}>
|
||||
<SideNav
|
||||
expandedState={expandedState}
|
||||
onNavigate={this.handleNavigation}
|
||||
pages={pages}
|
||||
toggleDisplaySideNav={toggleDisplaySideNav}
|
||||
toggleDisplaySideNav={this.hideSideNav}
|
||||
toggleExpandedState={toggleExpandedState}
|
||||
/>
|
||||
</Col>
|
||||
<Col
|
||||
md={8}
|
||||
smHidden={displaySideNav}
|
||||
xsHidden={displaySideNav}
|
||||
>
|
||||
<Col md={8} smHidden={displayMenu} xsHidden={displayMenu}>
|
||||
<main
|
||||
className='content'
|
||||
id='main'
|
||||
|
@ -6,23 +6,17 @@ import { createSideNavigationSaga } from './side-navigation-saga';
|
||||
export const ns = 'guideNav';
|
||||
|
||||
const initialState = {
|
||||
displaySideNav: false,
|
||||
displayMenu: false,
|
||||
expandedState: {}
|
||||
};
|
||||
|
||||
const types = createTypes(
|
||||
['toggleExpandedState', 'toggleDisplaySideNav', 'toggleDisplayMenu'],
|
||||
ns
|
||||
);
|
||||
const types = createTypes(['toggleExpandedState', 'toggleDisplayMenu'], ns);
|
||||
|
||||
export const sagas = [...createSideNavigationSaga(types)];
|
||||
|
||||
export const toggleExpandedState = createAction(types.toggleExpandedState);
|
||||
export const toggleDisplaySideNav = createAction(types.toggleDisplaySideNav);
|
||||
export const toggleDisplayMenu = createAction(types.toggleDisplayMenu);
|
||||
|
||||
export const displaySideNavSelector = state => state[ns].displaySideNav;
|
||||
export const displayMenuSelector = state => state[ns].displayMenu;
|
||||
export const expandedStateSelector = state => state[ns].expandedState;
|
||||
|
||||
@ -35,11 +29,6 @@ export const reducer = handleActions(
|
||||
[payload]: !state.expandedState[payload]
|
||||
}
|
||||
}),
|
||||
[types.toggleDisplaySideNav]: state => ({
|
||||
...state,
|
||||
displayMenu: !state.displayMenu,
|
||||
displaySideNav: !state.displaySideNav
|
||||
}),
|
||||
[types.toggleDisplayMenu]: state => ({
|
||||
...state,
|
||||
displayMenu: !state.displayMenu
|
||||
|
Loading…
x
Reference in New Issue
Block a user