navbar hide on scroll behavior.

Add basic hide on scroll behavior for navbar. As described in

https://material.google.com/patterns/scrolling-techniques.html#scrolling-techniques-app-bar-scrollable-regions
old
Alex Cornejo 2016-08-25 00:14:35 -07:00
parent 0d7d78f3b1
commit 4d5f4cf02f
3 changed files with 100 additions and 62 deletions

View File

@ -1,67 +1,95 @@
import React, { PropTypes } from 'react';
import ReactDOM from 'react-dom';
import classnames from 'classnames';
import { themr } from 'react-css-themr';
import { APP_BAR } from '../identifiers.js';
import InjectIconButton from '../button/IconButton.js';
const factory = (IconButton) => {
const AppBar = ({ children, leftIcon, onLeftIconClick, onRightIconClick, rightIcon, theme, title, ...props }) => {
const className = classnames(theme.appBar, {
[theme.fixed]: props.fixed,
[theme.flat]: props.flat
}, props.className);
return (
<header className={className} data-react-toolbox='app-bar'>
{leftIcon && <IconButton
inverse
className={classnames(theme.leftIcon)}
onClick={onLeftIconClick}
icon={leftIcon} />
}
{title && <h1 className={classnames(theme.title)}>{title}</h1>}
{children}
{rightIcon && <IconButton
inverse
className={classnames(theme.rightIcon)}
onClick={onRightIconClick}
icon={rightIcon} />
}
</header>
);
};
AppBar.propTypes = {
children: PropTypes.node,
className: PropTypes.string,
fixed: PropTypes.bool,
flat: PropTypes.bool,
leftIcon: PropTypes.oneOfType([
PropTypes.string,
PropTypes.element
]),
onLeftIconClick: PropTypes.func,
onRightIconClick: PropTypes.func,
rightIcon: PropTypes.oneOfType([
PropTypes.string,
PropTypes.element
]),
theme: PropTypes.shape({
appBar: PropTypes.string,
fixed: PropTypes.string,
flat: PropTypes.string,
leftIcon: PropTypes.string,
rightIcon: PropTypes.string,
class AppBar extends React.Component {
static propTypes = {
children: PropTypes.node,
className: PropTypes.string,
fixed: PropTypes.bool,
flat: PropTypes.bool,
leftIcon: PropTypes.oneOfType([
PropTypes.string,
PropTypes.element
]),
onLeftIconClick: PropTypes.func,
onRightIconClick: PropTypes.func,
rightIcon: PropTypes.oneOfType([
PropTypes.string,
PropTypes.element
]),
scrollHide: PropTypes.bool,
theme: PropTypes.shape({
appBar: PropTypes.string,
fixed: PropTypes.string,
flat: PropTypes.string,
leftIcon: PropTypes.string,
rightIcon: PropTypes.string,
title: PropTypes.string
}),
title: PropTypes.string
}),
title: PropTypes.string
};
};
AppBar.defaultProps = {
className: '',
fixed: false,
flat: false
};
static defaultProps = {
className: '',
fixed: false,
flat: false,
scrollHide: false
};
state = {hidden: false, height: 0};
componentDidMount () {
window.addEventListener('scroll', this.handleScroll);
const height = ReactDOM.findDOMNode(this).clientHeight;
this.setState({height});
this.curScroll = window.scrollY;
}
componentWillUnmount () {
window.removeEventListener('scroll', this.handleScroll);
}
handleScroll = () => {
if (!this.props.scrollHide) return;
const scrollDiff = this.curScroll - window.scrollY;
const hidden = scrollDiff < 0 && window.scrollY !== undefined && window.scrollY > this.state.height;
this.setState({hidden});
this.curScroll = window.scrollY;
};
render () {
const { children, leftIcon, onLeftIconClick, onRightIconClick, rightIcon, theme, title } = this.props;
const className = classnames(theme.appBar, {
[theme.fixed]: this.props.fixed,
[theme.flat]: this.props.flat,
[theme.scrollHide]: this.state.hidden
}, this.props.className);
return (
<header className={className} data-react-toolbox='app-bar'>
{leftIcon && <IconButton
inverse
className={classnames(theme.leftIcon)}
onClick={onLeftIconClick}
icon={leftIcon} />
}
{title && <h1 className={classnames(theme.title)}>{title}</h1>}
{children}
{rightIcon && <IconButton
inverse
className={classnames(theme.rightIcon)}
onClick={onRightIconClick}
icon={rightIcon} />
}
</header>
);
}
}
return AppBar;
};

View File

@ -33,10 +33,12 @@ The `AppBar` component provides properties for the common use cases of `title`,
## Theme
| Name | Description|
|:------------|:-----------|
| `appBar` | Used for the component root element.|
| `fixed` | Added to the root element when the app bar is fixed.|
| `title` | Added to the title element of the app bar.|
| `leftIcon` | Added to the left icon element when the app bar.|
| `rightIcon` | Added to the right icon element when the app bar.|
| Name | Description|
|:-------------|:-----------|
| `appBar` | Used for the component root element.|
| `fixed` | Added to the root element when the app bar is fixed.|
| `flat` | Added to the root element when the app bar is flat.|
| `title` | Added to the title element of the app bar.|
| `leftIcon` | Added to the left icon element when the app bar.|
| `rightIcon` | Added to the right icon element when the app bar.|
| `scrollHide` | Added to the root element when the app bar is hidden during scroll.|

View File

@ -54,4 +54,12 @@
margin-right: -1.2 * $unit;
margin-left: auto;
}
transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
transition-duration: .5s;
transition-property: transform;
&.scrollHide {
transform: translateY(-100%);
}
}