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

前端 未结 3 848
说谎
说谎 2021-02-09 08:40

As per Material Design guidelines:

Upon scrolling, the top app bar can […] transform in the following ways:
- Scrolling upward hides the top app bar

相关标签:
3条回答
  • 2021-02-09 08:58

    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);
    
    0 讨论(0)
  • 2021-02-09 09:13

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

    0 讨论(0)
  • 2021-02-09 09:19

    in the current version of Material-ui, you can simply use the following

    import clsx from "clsx";
    import useScrollTrigger from "@material-ui/core/useScrollTrigger";
    const trigger = useScrollTrigger();
    
    <AppBar className={trigger ? classes.show : classes.hide}>
    </AppBar>
    

    https://material-ui.com/components/app-bar/#usescrolltrigger-options-trigger

    0 讨论(0)
提交回复
热议问题