Merge pull request #12288 from BerkeleyTrue/feat/add-dropdown-nav
feat(nav): Add dropdown menu
This commit is contained in:
@ -33,7 +33,8 @@
|
|||||||
z-index: @zindex-dropdown;
|
z-index: @zindex-dropdown;
|
||||||
display: none; // none by default, but block on "open" of the menu
|
display: none; // none by default, but block on "open" of the menu
|
||||||
float: left;
|
float: left;
|
||||||
min-width: 160px;
|
min-width: 0;
|
||||||
|
width: 100%;
|
||||||
padding: 5px 0;
|
padding: 5px 0;
|
||||||
margin: 2px 0 0; // override default ul
|
margin: 2px 0 0; // override default ul
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
@ -235,9 +235,9 @@
|
|||||||
@dropdown-divider-bg: #e5e5e5;
|
@dropdown-divider-bg: #e5e5e5;
|
||||||
|
|
||||||
//** Dropdown link text color.
|
//** Dropdown link text color.
|
||||||
@dropdown-link-color: @gray-dark;
|
@dropdown-link-color: darkgreen;
|
||||||
//** Hover color for dropdown links.
|
//** Hover color for dropdown links.
|
||||||
@dropdown-link-hover-color: darken(@gray-dark, 5%);
|
@dropdown-link-hover-color: darkgreen;
|
||||||
//** Hover background for dropdown links.
|
//** Hover background for dropdown links.
|
||||||
@dropdown-link-hover-bg: #f5f5f5;
|
@dropdown-link-hover-bg: #f5f5f5;
|
||||||
|
|
||||||
@ -365,8 +365,8 @@
|
|||||||
@navbar-default-link-color: @gray-lighter;
|
@navbar-default-link-color: @gray-lighter;
|
||||||
@navbar-default-link-hover-color: darkgreen;
|
@navbar-default-link-hover-color: darkgreen;
|
||||||
@navbar-default-link-hover-bg: @gray-lighter;
|
@navbar-default-link-hover-bg: @gray-lighter;
|
||||||
@navbar-default-link-active-color: @gray-lighter;
|
@navbar-default-link-active-color: darkgreen;
|
||||||
@navbar-default-link-active-bg: darken(@navbar-default-bg, 6.5%);
|
@navbar-default-link-active-bg: @gray-lighter;
|
||||||
@navbar-default-link-disabled-color: #ccc;
|
@navbar-default-link-disabled-color: #ccc;
|
||||||
@navbar-default-link-disabled-bg: transparent;
|
@navbar-default-link-disabled-bg: transparent;
|
||||||
|
|
||||||
|
@ -3,10 +3,12 @@ import ReactDOM from 'react-dom';
|
|||||||
import { LinkContainer } from 'react-router-bootstrap';
|
import { LinkContainer } from 'react-router-bootstrap';
|
||||||
import {
|
import {
|
||||||
Col,
|
Col,
|
||||||
|
MenuItem,
|
||||||
Nav,
|
Nav,
|
||||||
NavbarBrand,
|
NavDropdown,
|
||||||
|
NavItem,
|
||||||
Navbar,
|
Navbar,
|
||||||
NavItem
|
NavbarBrand
|
||||||
} from 'react-bootstrap';
|
} from 'react-bootstrap';
|
||||||
|
|
||||||
import navLinks from './links.json';
|
import navLinks from './links.json';
|
||||||
@ -76,36 +78,45 @@ export default class FCCNav extends React.Component {
|
|||||||
this.props.loadCurrentChallenge();
|
this.props.loadCurrentChallenge();
|
||||||
}
|
}
|
||||||
|
|
||||||
renderLinks() {
|
renderLink(isNavItem, { isReact, isDropdown, content, link, links, target }) {
|
||||||
return navLinks.map(({ content, link, react, target }, index) => {
|
const Component = isNavItem ? NavItem : MenuItem;
|
||||||
if (react) {
|
if (isDropdown) {
|
||||||
return (
|
|
||||||
<LinkContainer
|
|
||||||
eventKey={ index + 2 }
|
|
||||||
key={ content }
|
|
||||||
onClick={ this[`handle${content}Click`] }
|
|
||||||
to={ link }
|
|
||||||
>
|
|
||||||
<NavItem
|
|
||||||
target={ target || null }
|
|
||||||
>
|
|
||||||
{ content }
|
|
||||||
</NavItem>
|
|
||||||
</LinkContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<NavItem
|
<NavDropdown
|
||||||
eventKey={ index + 1 }
|
id={ `nav-${content}-dropdown` }
|
||||||
href={ link }
|
key={ content }
|
||||||
|
noCaret={ true }
|
||||||
|
title={ content }
|
||||||
|
>
|
||||||
|
{ links.map(this.renderLink.bind(this, false)) }
|
||||||
|
</NavDropdown>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (isReact) {
|
||||||
|
return (
|
||||||
|
<LinkContainer
|
||||||
key={ content }
|
key={ content }
|
||||||
onClick={ this[`handle${content}Click`] }
|
onClick={ this[`handle${content}Click`] }
|
||||||
target={ target || null }
|
to={ link }
|
||||||
>
|
>
|
||||||
{ content }
|
<Component
|
||||||
</NavItem>
|
target={ target || null }
|
||||||
|
>
|
||||||
|
{ content }
|
||||||
|
</Component>
|
||||||
|
</LinkContainer>
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
|
return (
|
||||||
|
<Component
|
||||||
|
href={ link }
|
||||||
|
key={ content }
|
||||||
|
onClick={ this[`handle${content}Click`] }
|
||||||
|
target={ target || null }
|
||||||
|
>
|
||||||
|
{ content }
|
||||||
|
</Component>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderSignIn(username, points, picture, showLoading) {
|
renderSignIn(username, points, picture, showLoading) {
|
||||||
@ -123,7 +134,6 @@ export default class FCCNav extends React.Component {
|
|||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<NavItem
|
<NavItem
|
||||||
eventKey={ 2 }
|
|
||||||
href='/signup'
|
href='/signup'
|
||||||
key='signup'
|
key='signup'
|
||||||
>
|
>
|
||||||
@ -140,6 +150,17 @@ export default class FCCNav extends React.Component {
|
|||||||
picture,
|
picture,
|
||||||
showLoading
|
showLoading
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
let navLinksCache;
|
||||||
|
|
||||||
|
if (this._navLinksCache) {
|
||||||
|
navLinksCache = this._navLinksCache;
|
||||||
|
} else {
|
||||||
|
// we cache the rendered static links on the instance
|
||||||
|
// these do not change for the lifetime of the app
|
||||||
|
navLinksCache = this._navLinksCache = navLinks.map(
|
||||||
|
this.renderLink.bind(this, true)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Navbar
|
<Navbar
|
||||||
@ -167,7 +188,7 @@ export default class FCCNav extends React.Component {
|
|||||||
navbar={ true }
|
navbar={ true }
|
||||||
pullRight={ true }
|
pullRight={ true }
|
||||||
>
|
>
|
||||||
{ this.renderLinks() }
|
{ navLinksCache }
|
||||||
{ this.renderSignIn(username, points, picture, showLoading) }
|
{ this.renderSignIn(username, points, picture, showLoading) }
|
||||||
</Nav>
|
</Nav>
|
||||||
</Navbar.Collapse>
|
</Navbar.Collapse>
|
||||||
|
@ -1,18 +1,22 @@
|
|||||||
[{
|
[{
|
||||||
|
"content": "Community",
|
||||||
|
"isDropdown": true,
|
||||||
|
"links": [{
|
||||||
|
"content": "About",
|
||||||
|
"link": "/about"
|
||||||
|
}, {
|
||||||
|
"content": "Forum",
|
||||||
|
"link": "https://forum.freecodecamp.com/",
|
||||||
|
"target": "_blank"
|
||||||
|
}, {
|
||||||
|
"content": "Chat",
|
||||||
|
"link": "https://gitter.im/freecodecamp/home",
|
||||||
|
"target": "_blank"
|
||||||
|
}]
|
||||||
|
},{
|
||||||
"content": "Map",
|
"content": "Map",
|
||||||
"link": "/map",
|
"link": "/map",
|
||||||
"react": true
|
"isReact": true
|
||||||
},{
|
|
||||||
"content": "Chat",
|
|
||||||
"link": "https://gitter.im/freecodecamp/home",
|
|
||||||
"target": "_blank"
|
|
||||||
},{
|
|
||||||
"content": "Forum",
|
|
||||||
"link": "https://forum.freecodecamp.com/",
|
|
||||||
"target": "_blank"
|
|
||||||
},{
|
|
||||||
"content": "About",
|
|
||||||
"link": "/about"
|
|
||||||
},{
|
},{
|
||||||
"content": "Shop",
|
"content": "Shop",
|
||||||
"link": "/shop"
|
"link": "/shop"
|
||||||
|
@ -7,14 +7,17 @@ nav.navbar.navbar-default.navbar-fixed-top.nav-height
|
|||||||
img.img-responsive.nav-logo(src='https://s3.amazonaws.com/freecodecamp/freecodecamp_logo.svg', alt='learn to code javascript at Free Code Camp logo')
|
img.img-responsive.nav-logo(src='https://s3.amazonaws.com/freecodecamp/freecodecamp_logo.svg', alt='learn to code javascript at Free Code Camp logo')
|
||||||
.collapse.navbar-collapse
|
.collapse.navbar-collapse
|
||||||
ul.nav.navbar-nav.navbar-right.hamburger-dropdown
|
ul.nav.navbar-nav.navbar-right.hamburger-dropdown
|
||||||
|
li.dropdown
|
||||||
|
a.dropdown-toggle(data-toggle='dropdown' role='button' href='#' aria-haspopup='true') Community
|
||||||
|
ul.dropdown-menu
|
||||||
|
li
|
||||||
|
a(href='/about') About
|
||||||
|
li
|
||||||
|
a(href='https://gitter.im/freecodecamp/home' target='_blank') Chat
|
||||||
|
li
|
||||||
|
a(href='https://forum.freecodecamp.com', target='_blank') Forum
|
||||||
li
|
li
|
||||||
a(href='/map') Map
|
a(href='/map') Map
|
||||||
li
|
|
||||||
a(href='https://gitter.im/freecodecamp/home' target='_blank') Chat
|
|
||||||
li
|
|
||||||
a(href='https://forum.freecodecamp.com', target='_blank') Forum
|
|
||||||
li
|
|
||||||
a(href='/about') About
|
|
||||||
li
|
li
|
||||||
a(href='/shop') Shop
|
a(href='/shop') Shop
|
||||||
if !user
|
if !user
|
||||||
|
Reference in New Issue
Block a user