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-regionsold
parent
0d7d78f3b1
commit
4d5f4cf02f
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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.|
|
||||
|
|
|
@ -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%);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue