From 3a4e62da44a77b5b96e319259eb9f46f529d2430 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Fri, 30 Dec 2016 15:23:58 -0800 Subject: [PATCH] feat(nav): Add dropdown menu --- client/less/lib/bootstrap/dropdowns.less | 3 +- client/less/lib/bootstrap/variables.less | 8 +-- common/app/components/Nav/Nav.jsx | 79 +++++++++++++++--------- common/app/components/Nav/links.json | 28 +++++---- server/views/partials/navbar.jade | 15 +++-- 5 files changed, 81 insertions(+), 52 deletions(-) diff --git a/client/less/lib/bootstrap/dropdowns.less b/client/less/lib/bootstrap/dropdowns.less index 84a48c14135502..19fa1fee157da1 100755 --- a/client/less/lib/bootstrap/dropdowns.less +++ b/client/less/lib/bootstrap/dropdowns.less @@ -33,7 +33,8 @@ z-index: @zindex-dropdown; display: none; // none by default, but block on "open" of the menu float: left; - min-width: 160px; + min-width: 0; + width: 100%; padding: 5px 0; margin: 2px 0 0; // override default ul list-style: none; diff --git a/client/less/lib/bootstrap/variables.less b/client/less/lib/bootstrap/variables.less index 0e411ce3c7c696..cddcc5a1deb4c1 100755 --- a/client/less/lib/bootstrap/variables.less +++ b/client/less/lib/bootstrap/variables.less @@ -235,9 +235,9 @@ @dropdown-divider-bg: #e5e5e5; //** Dropdown link text color. -@dropdown-link-color: @gray-dark; +@dropdown-link-color: darkgreen; //** Hover color for dropdown links. -@dropdown-link-hover-color: darken(@gray-dark, 5%); +@dropdown-link-hover-color: darkgreen; //** Hover background for dropdown links. @dropdown-link-hover-bg: #f5f5f5; @@ -365,8 +365,8 @@ @navbar-default-link-color: @gray-lighter; @navbar-default-link-hover-color: darkgreen; @navbar-default-link-hover-bg: @gray-lighter; -@navbar-default-link-active-color: @gray-lighter; -@navbar-default-link-active-bg: darken(@navbar-default-bg, 6.5%); +@navbar-default-link-active-color: darkgreen; +@navbar-default-link-active-bg: @gray-lighter; @navbar-default-link-disabled-color: #ccc; @navbar-default-link-disabled-bg: transparent; diff --git a/common/app/components/Nav/Nav.jsx b/common/app/components/Nav/Nav.jsx index 9447d7268185bd..9a953c00a60a53 100644 --- a/common/app/components/Nav/Nav.jsx +++ b/common/app/components/Nav/Nav.jsx @@ -3,10 +3,12 @@ import ReactDOM from 'react-dom'; import { LinkContainer } from 'react-router-bootstrap'; import { Col, + MenuItem, Nav, - NavbarBrand, + NavDropdown, + NavItem, Navbar, - NavItem + NavbarBrand } from 'react-bootstrap'; import navLinks from './links.json'; @@ -76,36 +78,45 @@ export default class FCCNav extends React.Component { this.props.loadCurrentChallenge(); } - renderLinks() { - return navLinks.map(({ content, link, react, target }, index) => { - if (react) { - return ( - - - { content } - - - ); - } + renderLink(isNavItem, { isReact, isDropdown, content, link, links, target }) { + const Component = isNavItem ? NavItem : MenuItem; + if (isDropdown) { return ( - + { links.map(this.renderLink.bind(this, false)) } + + ); + } + if (isReact) { + return ( + - { content } - + + { content } + + ); - }); + } + return ( + + { content } + + ); } renderSignIn(username, points, picture, showLoading) { @@ -123,7 +134,6 @@ export default class FCCNav extends React.Component { } else { return ( @@ -140,6 +150,17 @@ export default class FCCNav extends React.Component { picture, showLoading } = 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 ( - { this.renderLinks() } + { navLinksCache } { this.renderSignIn(username, points, picture, showLoading) } diff --git a/common/app/components/Nav/links.json b/common/app/components/Nav/links.json index cf60ed8acfcaa5..b73f645a8c72e3 100644 --- a/common/app/components/Nav/links.json +++ b/common/app/components/Nav/links.json @@ -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", "link": "/map", - "react": true -},{ - "content": "Chat", - "link": "https://gitter.im/freecodecamp/home", - "target": "_blank" -},{ - "content": "Forum", - "link": "https://forum.freecodecamp.com/", - "target": "_blank" -},{ - "content": "About", - "link": "/about" + "isReact": true },{ "content": "Shop", "link": "/shop" diff --git a/server/views/partials/navbar.jade b/server/views/partials/navbar.jade index 2f4a796f11e6aa..bf2db91a82f7bf 100644 --- a/server/views/partials/navbar.jade +++ b/server/views/partials/navbar.jade @@ -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') .collapse.navbar-collapse 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 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 a(href='/shop') Shop if !user