-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #187 from dabapps/nav-bar
Nav bar
- Loading branch information
Showing
12 changed files
with
497 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
body.with-fixed-nav-bar { | ||
padding-top: @nav-bar-height; | ||
} | ||
|
||
.nav-bar { | ||
.clearfix(); | ||
padding: @padding-base 0; | ||
background-color: @nav-bar-background; | ||
border-bottom: @nav-bar-border; | ||
box-shadow: @shadow-hard; | ||
height: @nav-bar-height; | ||
transition: ease-in-out 0.2s transform, ease-in-out 0.2s box-shadow; | ||
|
||
&.no-shaddow { | ||
box-shadow: @shadow-none; | ||
} | ||
|
||
&.fixed { | ||
position: fixed; | ||
top: 0; | ||
left: 0; | ||
width: 100%; | ||
z-index: 500; | ||
} | ||
|
||
&.shy.hidden { | ||
transform: translate(0, -100%); | ||
box-shadow: @shadow-none; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#### Example | ||
|
||
```js | ||
class NavBarExample extends React.Component { | ||
constructor (props) { | ||
super(props); | ||
|
||
this.state = {}; | ||
|
||
this.onChange = this.onChange.bind(this); | ||
} | ||
|
||
render () { | ||
const { | ||
type | ||
} = this.state; | ||
|
||
return ( | ||
<div> | ||
<NavBar fixed={type === 'fixed'} shy={type === 'shy'}> | ||
<Column> | ||
<SpacedGroup> | ||
<Button> | ||
Home | ||
</Button> | ||
<Button> | ||
About | ||
</Button> | ||
<Button> | ||
Contact | ||
</Button> | ||
</SpacedGroup> | ||
</Column> | ||
</NavBar> | ||
<FormGroup block> | ||
<label> | ||
NavBar type | ||
</label> | ||
<select onChange={this.onChange}> | ||
<option value="static"> | ||
Static | ||
</option> | ||
<option value="fixed"> | ||
Fixed | ||
</option> | ||
<option value="shy"> | ||
Shy | ||
</option> | ||
</select> | ||
</FormGroup> | ||
</div> | ||
); | ||
} | ||
|
||
onChange (event) { | ||
this.setState({ | ||
type: event.target.value | ||
}); | ||
} | ||
} | ||
|
||
<NavBarExample /> | ||
``` | ||
|
||
#### Less variables | ||
|
||
```less | ||
@nav-bar-background: @body-background; // @white; | ||
@nav-bar-border: @border-base; | ||
@nav-bar-height: @input-height + @padding-base * 2; | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
import * as classNames from 'classnames'; | ||
import * as React from 'react'; | ||
import { HTMLProps, PureComponent } from 'react'; | ||
import * as ReactDOM from 'react-dom'; | ||
import { ComponentProps } from '../../types'; | ||
import { addClassName, getScrollOffset, removeClassName } from '../../utils'; | ||
|
||
const WITH_FIXED_NAV_BAR = 'with-fixed-nav-bar'; | ||
|
||
export interface NavBarProps extends ComponentProps, HTMLProps<HTMLElement> { | ||
/** | ||
* Fix the navbar to the top of the screen | ||
*/ | ||
fixed?: boolean; | ||
/** | ||
* Hide the navbar when scrolling down, but display when scrolling up | ||
*/ | ||
shy?: boolean; | ||
/** | ||
* Remove NavBar shadow | ||
*/ | ||
noShadow?: boolean; | ||
} | ||
|
||
export interface NavBarState { | ||
hidden: boolean; | ||
} | ||
|
||
export class NavBar extends PureComponent<NavBarProps, NavBarState> { | ||
private previousScrollY: number; | ||
|
||
public constructor (props: NavBarProps) { | ||
super(props); | ||
|
||
this.previousScrollY = getScrollOffset().y; | ||
|
||
this.state = { | ||
hidden: false, | ||
}; | ||
} | ||
|
||
public componentWillMount () { | ||
this.updateBodyClass(this.props); | ||
this.toggleShyListeners(this.props); | ||
} | ||
|
||
public componentWillUpdate (nextProps: NavBarProps) { | ||
if (this.props.shy !== nextProps.shy) { | ||
this.toggleShyListeners(nextProps); | ||
} | ||
|
||
if (this.props.fixed !== nextProps.fixed || this.props.shy !== nextProps.shy) { | ||
this.updateBodyClass(nextProps); | ||
} | ||
} | ||
|
||
public componentWillUnmount () { | ||
window.removeEventListener('scroll', this.hideOrShowNavBar); | ||
window.removeEventListener('resize', this.hideOrShowNavBar); | ||
} | ||
|
||
public render () { | ||
const { | ||
children, | ||
className, | ||
fixed, | ||
shy, | ||
noShadow, | ||
component: Component = 'div', | ||
...remainingProps, | ||
} = this.props; | ||
|
||
const { | ||
hidden, | ||
} = this.state; | ||
|
||
const myClassNames = [ | ||
'nav-bar', | ||
fixed || shy ? 'fixed' : null, | ||
shy ? 'shy' : null, | ||
hidden ? 'hidden' : null, | ||
noShadow ? 'no-shadow' : null, | ||
className | ||
]; | ||
|
||
return ( | ||
<Component {...remainingProps} className={classNames(myClassNames)}> | ||
{children} | ||
</Component> | ||
); | ||
} | ||
|
||
private updateBodyClass (props: NavBarProps) { | ||
const { fixed, shy } = props; | ||
|
||
if (fixed || shy) { | ||
addClassName(document.body, WITH_FIXED_NAV_BAR); | ||
} else { | ||
removeClassName(document.body, WITH_FIXED_NAV_BAR) | ||
} | ||
} | ||
|
||
private toggleShyListeners (props: NavBarProps) { | ||
const { shy } = props; | ||
|
||
if (shy) { | ||
window.addEventListener('scroll', this.hideOrShowNavBar); | ||
window.addEventListener('resize', this.hideOrShowNavBar); | ||
} else { | ||
window.removeEventListener('scroll', this.hideOrShowNavBar); | ||
window.removeEventListener('resize', this.hideOrShowNavBar); | ||
} | ||
} | ||
|
||
private hideOrShowNavBar = () => { | ||
const { y } = getScrollOffset(); | ||
const element = ReactDOM.findDOMNode(this); | ||
|
||
if (element) { | ||
const { height } = element.getBoundingClientRect(); | ||
|
||
if (y > this.previousScrollY && y > height) { | ||
this.setState({ | ||
hidden: true, | ||
}); | ||
} else if (y < this.previousScrollY) { | ||
this.setState({ | ||
hidden: false, | ||
}); | ||
} | ||
} | ||
|
||
this.previousScrollY = y; | ||
} | ||
} | ||
|
||
export default NavBar; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,10 @@ | ||
export const NBSP = '\u00a0'; | ||
|
||
export const MATCHES_WHITESPACE = /\s+/g; | ||
export const MATCHES_INITIAL_INDENTATION = /^([^\S\n]*)\S/; | ||
export const MATCHES_BLANK_FIRST_LINE = /^\s*\n/; | ||
export const MATCHES_BLANK_LAST_LINE = /\n\s*$/; | ||
|
||
export const MATCHES_AMPERSAND = /&/gi; | ||
export const MATCHES_AMPERSAND = /&/g; | ||
export const MATCHES_NON_WORD_CHARACTERS = /[\W_]+/gi; | ||
export const MATCHES_LEADING_AND_TRAILING_HYPHENS = /(^-+|-+$)/gi; | ||
export const MATCHES_LEADING_AND_TRAILING_HYPHENS = /(^-+|-+$)/g; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`NavBar should apply fixed class 1`] = ` | ||
<div | ||
className="nav-bar fixed" | ||
/> | ||
`; | ||
|
||
exports[`NavBar should apply no shadow class 1`] = ` | ||
<div | ||
className="nav-bar no-shadow" | ||
/> | ||
`; | ||
|
||
exports[`NavBar should apply shy class 1`] = ` | ||
<div | ||
className="nav-bar fixed shy" | ||
/> | ||
`; | ||
|
||
exports[`NavBar should apply the hidden class 1`] = ` | ||
<NavBar | ||
shy={true} | ||
> | ||
<div | ||
className="nav-bar fixed shy hidden" | ||
/> | ||
</NavBar> | ||
`; | ||
|
||
exports[`NavBar should match snapshot 1`] = ` | ||
<div | ||
className="nav-bar" | ||
/> | ||
`; | ||
|
||
exports[`NavBar should take regular element attributes 1`] = ` | ||
<div | ||
className="nav-bar my-class" | ||
/> | ||
`; |
Oops, something went wrong.