fix(git): Merge temp branch to fix/binButtons
This commit is contained in:
@ -328,7 +328,7 @@
|
||||
@grid-gutter-width: 30px;
|
||||
// Navbar collapse
|
||||
//** Point at which the navbar becomes uncollapsed.
|
||||
@grid-float-breakpoint: @screen-sm-min;
|
||||
@grid-float-breakpoint: 955px;
|
||||
//** Point at which the navbar begins collapsing.
|
||||
@grid-float-breakpoint-max: (@grid-float-breakpoint - 1);
|
||||
|
||||
|
47
common/app/Nav/LargeNav.jsx
Normal file
47
common/app/Nav/LargeNav.jsx
Normal file
@ -0,0 +1,47 @@
|
||||
import React from 'react';
|
||||
import Media from 'react-media';
|
||||
import { Col, Navbar, Row } from 'react-bootstrap';
|
||||
import FCCSearchBar from 'react-freecodecamp-search';
|
||||
import { NavLogo, BinButtons, NavLinks } from './components';
|
||||
|
||||
import propTypes from './navPropTypes';
|
||||
|
||||
function LargeNav({ clickOnLogo, clickOnMap, shouldShowMapButton, panes }) {
|
||||
return (
|
||||
<Media
|
||||
query='(min-width: 956px)'
|
||||
render={
|
||||
() => (
|
||||
<Row>
|
||||
<Col className='nav-component' sm={ 4 } xs={ 6 }>
|
||||
<Navbar.Header>
|
||||
<NavLogo clickOnLogo={ clickOnLogo } />
|
||||
<FCCSearchBar
|
||||
dropdown={ true }
|
||||
placeholder=
|
||||
' Search 8,000+ lessons, articles, and videos'
|
||||
/>
|
||||
</Navbar.Header>
|
||||
</Col>
|
||||
<Col className='nav-component bins' sm={ 4 } xs={ 6 }>
|
||||
<BinButtons panes={ panes } />
|
||||
</Col>
|
||||
<Col className='nav-component nav-links' sm={ 4 } xs={ 0 }>
|
||||
<Navbar.Collapse>
|
||||
<NavLinks
|
||||
clickOnMap={ clickOnMap }
|
||||
shouldShowMapButton={ shouldShowMapButton }
|
||||
/>
|
||||
</Navbar.Collapse>
|
||||
</Col>
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
LargeNav.displayName = 'LargeNav';
|
||||
LargeNav.propTypes = propTypes;
|
||||
|
||||
export default LargeNav;
|
52
common/app/Nav/MediumNav.jsx
Normal file
52
common/app/Nav/MediumNav.jsx
Normal file
@ -0,0 +1,52 @@
|
||||
import React from 'react';
|
||||
import Media from 'react-media';
|
||||
import { Col, Navbar, Row } from 'react-bootstrap';
|
||||
import FCCSearchBar from 'react-freecodecamp-search';
|
||||
import { NavLogo, BinButtons, NavLinks } from './components';
|
||||
|
||||
import propTypes from './navPropTypes';
|
||||
|
||||
function MediumNav({ clickOnLogo, clickOnMap, shouldShowMapButton, panes }) {
|
||||
return (
|
||||
<Media
|
||||
query={{ maxWidth: 955, minWidth: 751 }}
|
||||
render={
|
||||
() => (
|
||||
<div>
|
||||
<Row>
|
||||
<Navbar.Header className='medium-nav'>
|
||||
<div className='nav-component header'>
|
||||
<Navbar.Toggle />
|
||||
<NavLogo clickOnLogo={ clickOnLogo } />
|
||||
<FCCSearchBar
|
||||
dropdown={ true }
|
||||
placeholder=
|
||||
' Search 8,000+ lessons, articles, and videos'
|
||||
/>
|
||||
</div>
|
||||
<div className='nav-component bins'>
|
||||
<BinButtons panes={ panes } />
|
||||
</div>
|
||||
</Navbar.Header>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col xs={ 12 }>
|
||||
<Navbar.Collapse>
|
||||
<NavLinks
|
||||
clickOnMap={ clickOnMap }
|
||||
shouldShowMapButton={ shouldShowMapButton }
|
||||
/>
|
||||
</Navbar.Collapse>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
MediumNav.displayName = 'MediumNav';
|
||||
MediumNav.propTypes = propTypes;
|
||||
|
||||
export default MediumNav;
|
@ -1,19 +1,18 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import FCCSearchBar from 'react-freecodecamp-search';
|
||||
import {
|
||||
Navbar
|
||||
} from 'react-bootstrap';
|
||||
import { Navbar } from 'react-bootstrap';
|
||||
|
||||
import { BinButtons, NavLogo, NavLinks } from './components';
|
||||
import LargeNav from './LargeNav.jsx';
|
||||
import MediumNav from './MediumNav.jsx';
|
||||
import SmallNav from './SmallNav.jsx';
|
||||
import {
|
||||
clickOnLogo,
|
||||
clickOnMap
|
||||
} from './redux';
|
||||
import { panesSelector } from '../Panes/redux';
|
||||
import propTypes from './navPropTypes';
|
||||
|
||||
const mapStateToProps = createSelector(
|
||||
panesSelector,
|
||||
@ -63,13 +62,6 @@ function mergeProps(stateProps, dispatchProps, ownProps) {
|
||||
};
|
||||
}
|
||||
|
||||
const propTypes = {
|
||||
clickOnLogo: PropTypes.func.isRequired,
|
||||
clickOnMap: PropTypes.func.isRequired,
|
||||
panes: PropTypes.array,
|
||||
shouldShowMapButton: PropTypes.bool
|
||||
};
|
||||
|
||||
function FCCNav(props) {
|
||||
const {
|
||||
panes,
|
||||
@ -83,23 +75,24 @@ function FCCNav(props) {
|
||||
id='navbar'
|
||||
staticTop={ true }
|
||||
>
|
||||
<div className='nav-component-wrapper'>
|
||||
<Navbar.Header>
|
||||
<Navbar.Toggle children={ 'Menu' } />
|
||||
<NavLogo clickOnLogo={ clickOnLogo } />
|
||||
<FCCSearchBar
|
||||
dropdown={ true }
|
||||
placeholder=' Search 8,000+ lessons, articles, and videos'
|
||||
/>
|
||||
</Navbar.Header>
|
||||
<BinButtons panes={ panes } />
|
||||
<Navbar.Collapse>
|
||||
<NavLinks
|
||||
clickOnMap={ clickOnMap }
|
||||
shouldShowMapButton={ shouldShowMapButton }
|
||||
/>
|
||||
</Navbar.Collapse>
|
||||
</div>
|
||||
<LargeNav
|
||||
clickOnLogo={ clickOnLogo }
|
||||
clickOnMap={ clickOnMap }
|
||||
panes={ panes }
|
||||
shouldShowMapButton={ shouldShowMapButton }
|
||||
/>
|
||||
<MediumNav
|
||||
clickOnLogo={ clickOnLogo }
|
||||
clickOnMap={ clickOnMap }
|
||||
panes={ panes }
|
||||
shouldShowMapButton={ shouldShowMapButton }
|
||||
/>
|
||||
<SmallNav
|
||||
clickOnLogo={ clickOnLogo }
|
||||
clickOnMap={ clickOnMap }
|
||||
panes={ panes }
|
||||
shouldShowMapButton={ shouldShowMapButton }
|
||||
/>
|
||||
</Navbar>
|
||||
);
|
||||
}
|
||||
|
53
common/app/Nav/SmallNav.jsx
Normal file
53
common/app/Nav/SmallNav.jsx
Normal file
@ -0,0 +1,53 @@
|
||||
import React from 'react';
|
||||
import Media from 'react-media';
|
||||
import { Col, Navbar, Row } from 'react-bootstrap';
|
||||
import FCCSearchBar from 'react-freecodecamp-search';
|
||||
import { NavLogo, BinButtons, NavLinks } from './components';
|
||||
|
||||
import propTypes from './navPropTypes';
|
||||
|
||||
function SmallNav({ clickOnLogo, clickOnMap, shouldShowMapButton, panes }) {
|
||||
return (
|
||||
<Media
|
||||
query='(max-width: 750px)'
|
||||
render={
|
||||
() => (
|
||||
<div>
|
||||
<Row>
|
||||
<Navbar.Header className='small-nav'>
|
||||
<div className='nav-component header'>
|
||||
<Navbar.Toggle />
|
||||
<NavLogo clickOnLogo={ clickOnLogo } />
|
||||
</div>
|
||||
<div className='nav-component bins'>
|
||||
<BinButtons panes={ panes } />
|
||||
</div>
|
||||
</Navbar.Header>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col xs={ 12 }>
|
||||
<Navbar.Collapse>
|
||||
<NavLinks
|
||||
clickOnMap={ clickOnMap }
|
||||
shouldShowMapButton={ shouldShowMapButton }
|
||||
>
|
||||
<FCCSearchBar
|
||||
dropdown={ true }
|
||||
placeholder=
|
||||
' Search 8,000+ lessons, articles, and videos'
|
||||
/>
|
||||
</NavLinks>
|
||||
</Navbar.Collapse>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
SmallNav.displayName = 'SmallNav';
|
||||
SmallNav.propTypes = propTypes;
|
||||
|
||||
export default SmallNav;
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { NavItem } from 'react-bootstrap';
|
||||
import { Button } from 'react-bootstrap';
|
||||
|
||||
const propTypes = {
|
||||
content: PropTypes.string,
|
||||
@ -9,11 +9,12 @@ const propTypes = {
|
||||
|
||||
export default function BinButton({ content, handleClick }) {
|
||||
return (
|
||||
<NavItem
|
||||
<Button
|
||||
bsStyle='primary'
|
||||
onClick={ handleClick }
|
||||
>
|
||||
{ content }
|
||||
</NavItem>
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
BinButton.displayName = 'BinButton';
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Nav } from 'react-bootstrap';
|
||||
import { ButtonGroup } from 'react-bootstrap';
|
||||
import BinButton from './Bin-Button.jsx';
|
||||
|
||||
const propTypes = {
|
||||
@ -14,19 +14,17 @@ const propTypes = {
|
||||
|
||||
function BinButtons({ panes }) {
|
||||
return (
|
||||
<div id='bin-buttons'>
|
||||
<Nav>
|
||||
{
|
||||
panes.map(({ content, actionCreator }) => (
|
||||
<BinButton
|
||||
content={ content }
|
||||
handleClick={ actionCreator }
|
||||
key={ content }
|
||||
/>
|
||||
))
|
||||
}
|
||||
</Nav>
|
||||
</div>
|
||||
<ButtonGroup>
|
||||
{
|
||||
panes.map(({ content, actionCreator }) => (
|
||||
<BinButton
|
||||
content={ content }
|
||||
handleClick={ actionCreator }
|
||||
key={ content }
|
||||
/>
|
||||
))
|
||||
}
|
||||
</ButtonGroup>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -57,9 +57,11 @@ const navLinkPropType = PropTypes.shape({
|
||||
});
|
||||
|
||||
const propTypes = {
|
||||
children: PropTypes.any,
|
||||
clickOnMap: PropTypes.func.isRequired,
|
||||
closeDropdown: PropTypes.func.isRequired,
|
||||
isDropdownOpen: PropTypes.bool,
|
||||
isInNav: PropTypes.bool,
|
||||
isSignedIn: PropTypes.bool,
|
||||
navLinks: PropTypes.arrayOf(navLinkPropType),
|
||||
openDropdown: PropTypes.func.isRequired,
|
||||
@ -86,8 +88,6 @@ class NavLinks extends PureComponent {
|
||||
key={ content }
|
||||
noCaret={ true }
|
||||
onClick={ openDropdown }
|
||||
onMouseEnter={ openDropdown }
|
||||
onMouseLeave={ closeDropdown }
|
||||
onToggle={ isDropdownOpen ? closeDropdown : openDropdown }
|
||||
open={ isDropdownOpen }
|
||||
title={ content }
|
||||
@ -129,10 +129,13 @@ class NavLinks extends PureComponent {
|
||||
clickOnMap,
|
||||
showLoading,
|
||||
isSignedIn,
|
||||
navLinks
|
||||
navLinks,
|
||||
isInNav = true,
|
||||
children
|
||||
} = this.props;
|
||||
return (
|
||||
<Nav id='nav-links' navbar={ true } pullRight={ true }>
|
||||
{ children }
|
||||
{
|
||||
shouldShowMapButton ?
|
||||
<NoPropsPassThrough>
|
||||
@ -149,10 +152,11 @@ class NavLinks extends PureComponent {
|
||||
}
|
||||
{
|
||||
navLinks.map(
|
||||
this.renderLink.bind(this, true)
|
||||
this.renderLink.bind(this, isInNav)
|
||||
)
|
||||
}
|
||||
<SignUp
|
||||
isInDropDown={ !isInNav }
|
||||
showLoading={ showLoading }
|
||||
showSignUp={ !isSignedIn }
|
||||
/>
|
||||
|
@ -1,11 +1,12 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { NavbarBrand } from 'react-bootstrap';
|
||||
import Media from 'react-media';
|
||||
|
||||
const fCClogo = 'https://s3.amazonaws.com/freecodecamp/freecodecamp_logo.svg';
|
||||
// TODO @freecodecamp-team: place this glyph in S3 like above, PR in /assets
|
||||
const fCCglyph = 'https://raw.githubusercontent.com/freeCodeCamp/assets/' +
|
||||
'3b9cafc312802199ebba8b31fb1ed9b466a3efbb/assets/logos/FFCFire.png';
|
||||
'3b9cafc312802199ebba8b31fb1ed9b466a3efbb/assets/logos/FFCFire.png';
|
||||
|
||||
const propTypes = {
|
||||
clickOnLogo: PropTypes.func.isRequired
|
||||
@ -18,16 +19,23 @@ function NavLogo({ clickOnLogo }) {
|
||||
href='/challenges/current-challenge'
|
||||
onClick={ clickOnLogo }
|
||||
>
|
||||
<img
|
||||
alt='learn to code javascript at freeCodeCamp logo'
|
||||
className='img-responsive nav-logo logo'
|
||||
src={ fCClogo }
|
||||
/>
|
||||
<img
|
||||
alt='learn to code javascript at freeCodeCamp logo'
|
||||
className='img-responsive logo-glyph'
|
||||
src={ fCCglyph }
|
||||
/>
|
||||
<Media query='(min-width: 735px)'>
|
||||
{
|
||||
matches => matches ? (
|
||||
<img
|
||||
alt='learn to code javascript at freeCodeCamp logo'
|
||||
className='nav-logo logo'
|
||||
src={ fCClogo }
|
||||
/>
|
||||
) : (
|
||||
<img
|
||||
alt='learn to code javascript at freeCodeCamp logo'
|
||||
className='nav-logo logo'
|
||||
src={ fCCglyph }
|
||||
/>
|
||||
)
|
||||
}
|
||||
</Media>
|
||||
</a>
|
||||
</NavbarBrand>
|
||||
);
|
||||
|
@ -1,21 +1,29 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { NavItem } from 'react-bootstrap';
|
||||
import { MenuItem, NavItem } from 'react-bootstrap';
|
||||
|
||||
import { Link } from '../../Router';
|
||||
import { onRouteSettings } from '../../routes/Settings/redux';
|
||||
|
||||
const propTypes = {
|
||||
isInDropDown: PropTypes.bool,
|
||||
showLoading: PropTypes.bool,
|
||||
showSignUp: PropTypes.bool
|
||||
};
|
||||
|
||||
export default function SignUpButton({ showLoading, showSignUp }) {
|
||||
function SignUpButton({ isInDropDown, showLoading, showSignUp }) {
|
||||
if (showLoading) {
|
||||
return null;
|
||||
}
|
||||
if (showSignUp) {
|
||||
return (
|
||||
return isInDropDown ? (
|
||||
<MenuItem
|
||||
href='/signup'
|
||||
key='signup'
|
||||
>
|
||||
Sign Up
|
||||
</MenuItem>
|
||||
) : (
|
||||
<NavItem
|
||||
href='/signup'
|
||||
key='signup'
|
||||
@ -38,3 +46,5 @@ export default function SignUpButton({ showLoading, showSignUp }) {
|
||||
|
||||
SignUpButton.displayName = 'SignUpButton';
|
||||
SignUpButton.propTypes = propTypes;
|
||||
|
||||
export default SignUpButton;
|
||||
|
@ -223,64 +223,90 @@ li.nav-avatar {
|
||||
}
|
||||
}
|
||||
|
||||
.nav-component-wrapper {
|
||||
.nav-component {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
|
||||
&.header{
|
||||
|
||||
.navbar-brand {
|
||||
padding-left: 0px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&.bins {
|
||||
justify-content: center;
|
||||
|
||||
.nav {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
&.nav-links {
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.fcc_searchBar {
|
||||
width: auto;
|
||||
flex-grow: 1
|
||||
}
|
||||
|
||||
::-webkit-input-placeholder {
|
||||
color: @input-color-placeholder;
|
||||
}
|
||||
|
||||
::-moz-placeholder {
|
||||
color: @input-color-placeholder;
|
||||
}
|
||||
|
||||
::-ms-placeholder {
|
||||
color: @input-color-placeholder;
|
||||
}
|
||||
|
||||
::placeholder {
|
||||
color: @input-color-placeholder;
|
||||
}
|
||||
|
||||
.navbar-header {
|
||||
flex-grow: 1;
|
||||
::-webkit-input-placeholder {
|
||||
color: @input-color-placeholder;
|
||||
}
|
||||
|
||||
::-moz-placeholder {
|
||||
color: @input-color-placeholder;
|
||||
}
|
||||
|
||||
::-ms-placeholder {
|
||||
color: @input-color-placeholder;
|
||||
}
|
||||
|
||||
::placeholder {
|
||||
color: @input-color-placeholder;
|
||||
}
|
||||
}
|
||||
.navbar-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.logo-glyph {
|
||||
height: 28px;
|
||||
width: auto;
|
||||
}
|
||||
.medium-nav {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.logo {
|
||||
display: none !important;
|
||||
}
|
||||
.bins {
|
||||
justify-content: flex-end;
|
||||
|
||||
|
||||
@media (min-width: 992px) {
|
||||
.logo-glyph {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.small-nav {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.bins {
|
||||
justify-content: flex-end;
|
||||
|
||||
.btn {
|
||||
padding: 6px 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bins {
|
||||
|
||||
.btn {
|
||||
border-color: @brand-primary;
|
||||
background-color: white;
|
||||
|
||||
&:hover {
|
||||
background-color: @brand-primary;
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.nav-component-wrapper {
|
||||
display: block
|
||||
}
|
||||
|
||||
}
|
||||
|
8
common/app/Nav/navPropTypes.js
Normal file
8
common/app/Nav/navPropTypes.js
Normal file
@ -0,0 +1,8 @@
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
export default {
|
||||
clickOnLogo: PropTypes.func.isRequired,
|
||||
clickOnMap: PropTypes.func.isRequired,
|
||||
panes: PropTypes.array,
|
||||
shouldShowMapButton: PropTypes.bool
|
||||
};
|
23
package-lock.json
generated
23
package-lock.json
generated
@ -9231,6 +9231,14 @@
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
|
||||
},
|
||||
"json2mq": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz",
|
||||
"integrity": "sha1-tje9O6nqvhIsg+lyBIOusQ0skEo=",
|
||||
"requires": {
|
||||
"string-convert": "0.2.1"
|
||||
}
|
||||
},
|
||||
"json3": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz",
|
||||
@ -14079,6 +14087,16 @@
|
||||
"deep-equal": "1.0.1"
|
||||
}
|
||||
},
|
||||
"react-media": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/react-media/-/react-media-1.8.0.tgz",
|
||||
"integrity": "sha512-XcfqkDQj5/hmJod/kXUAZljJyMVkWrBWOkzwynAR8BXOGlbFLGBwezM0jQHtp2BrSymhf14/XrQrb3gGBnGK4g==",
|
||||
"requires": {
|
||||
"invariant": "2.2.2",
|
||||
"json2mq": "0.2.0",
|
||||
"prop-types": "15.6.0"
|
||||
}
|
||||
},
|
||||
"react-motion": {
|
||||
"version": "0.4.8",
|
||||
"resolved": "https://registry.npmjs.org/react-motion/-/react-motion-0.4.8.tgz",
|
||||
@ -16293,6 +16311,11 @@
|
||||
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
|
||||
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM="
|
||||
},
|
||||
"string-convert": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz",
|
||||
"integrity": "sha1-aYLMMEn7tM2F+LJFaLnZvznu/5c="
|
||||
},
|
||||
"string-length": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz",
|
||||
|
@ -119,6 +119,7 @@
|
||||
"react-freecodecamp-search": "^1.4.1",
|
||||
"react-helmet": "^5.2.0",
|
||||
"react-images": "^0.5.1",
|
||||
"react-media": "^1.8.0",
|
||||
"react-motion": "~0.4.2",
|
||||
"react-no-ssr": "^1.0.1",
|
||||
"react-notification": "git+https://github.com/BerkeleyTrue/react-notification.git#freecodecamp",
|
||||
|
Reference in New Issue
Block a user