Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make AppBar component from material-ui-next react to scroll events

As per Material Design guidelines:

Upon scrolling, the top app bar can […] transform in the following ways:
- Scrolling upward hides the top app bar
- Scrolling downward reveals the top app bar
When the top app bar scrolls, its elevation above other elements becomes apparent.

Is there any built-in approach to do this in material-ui-next or should it be considered as a new feature? Can you give a hint on how to achieve the animation of the AppBar component as described in the guidelines?

like image 470
Putzi San Avatar asked Oct 04 '17 14:10

Putzi San


People also ask

How do you add a scroll bar to a component in React?

You can apply it by placing the overflow-y:scroll in the id growth inside the style tag. Notice the scroll bar on the right side of the div .

How do you trigger a scroll event in React?

To handle the onScroll event in React: Set the onScroll prop on an element or add an event listener on the window object. Provide an event handler function. Access relevant properties on the event or window objects.

How do I add a scroll bar in material UI modal?

You need to use 'overflow = scroll' for modal style.


2 Answers

To my knowledge, there's no out-of-the-box solution for this at the moment. It's quite easy to implement though. Here is a snippet that subscribes to scroll events and hides or shows the AppBar accordingly:

const styles = {
  root: {
    flexGrow: 1,
  },
  show: {
    transform: 'translateY(0)',
    transition: 'transform .5s',
  },
  hide: {
    transform: 'translateY(-110%)',
    transition: 'transform .5s',
  },
};

class CollapsibleAppBar extends React.PureComponent {
  constructor(props) {
    super(props);

    this.state = {
      shouldShow: null,
    };

    this.lastScroll = null;

    this.handleScroll = this.handleScroll.bind(this);
    // Alternatively, you can throttle scroll events to avoid
    // updating the state too often. Here using lodash.
    // this.handleScroll = _.throttle(this.handleScroll.bind(this), 100);
  }

  componentDidMount() {
    window.addEventListener('scroll', this.handleScroll, { passive: true });
  }

  componentWillUnmount() {
    window.removeEventListener('scroll', this.handleScroll);
  }

  handleScroll(evt) {
    const lastScroll = window.scrollY;

    if (lastScroll === this.lastScroll) {
      return;
    }

    const shouldShow = (this.lastScroll !== null) ?  (lastScroll < this.lastScroll) : null;

    if (shouldShow !== this.state.shouldShow) {
      this.setState((prevState, props) => ({
        ...prevState,
        shouldShow,
      }));
    }

    this.lastScroll = lastScroll;
  }

  render() {
    const { classes } = this.props;
    return (
        <AppBar
      position="fixed"
      color="default"
      className={
            `${classes.root} ${
              this.state.shouldShow === null ? '' : (
                this.state.shouldShow ? classes.show : classes.hide
              )
            }`
          }
    >
          <Toolbar>
            <Typography variant="title" color="inherit">
              Title
            </Typography>
          </Toolbar>
        </AppBar>
    );
  }
}

CollapsibleAppBar.propTypes = {
  classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(CollapsibleAppBar);
like image 164
user8808265 Avatar answered Sep 23 '22 09:09

user8808265


For those who are still looking for built-in feature, Hide appbar on scroll is available in material-ui.

like image 29
109149 Avatar answered Sep 21 '22 09:09

109149