GithubHelp home page GithubHelp logo

kyleamathews / react-headroom Goto Github PK

View Code? Open in Web Editor NEW
1.8K 21.0 147.0 4.77 MB

Hide your header until you need it

Home Page: https://kyleamathews.github.io/react-headroom

License: MIT License

JavaScript 100.00%

react-headroom's Introduction

react-headroom

Hide your header until you need it.

Demo

http://kyleamathews.github.io/react-headroom

Install

npm install react-headroom

Usage

A simple example, see the docs site for more examples and documentation.

<Headroom>
  <h1>You can put anything you'd like inside the Headroom Component</h1>
</Headroom>

react-headroom's People

Contributors

autarc avatar barodeur avatar bebraw avatar bramschulting avatar brion25 avatar cmmartin avatar dbilgin avatar declanramsay avatar denkristoffer avatar emilecantin avatar emilyaviva avatar endymion1818 avatar fzaninotto avatar ggarnier avatar greenkeeperio-bot avatar ilshidur avatar ingro avatar janczizikow avatar jaredly avatar jaslakson avatar kandros avatar kyleamathews avatar lunsdorf avatar m-allanson avatar olerichter00 avatar plesiecki avatar robbestad avatar tbroussard avatar thangngoc89 avatar tzvigqb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-headroom's Issues

iOS Safari & desktop scroll bouncing is triggering the header

At the bottom of a page, when I continue to scroll down after I reach the bottom of the page, and release the scroll, it automatically scrolls up to the bottom of the page.
This automatic scroll pin the header.

Having an option to show the header when the scroll reach the end of the page could be useful, I think https://github.com/WickyNilliams/headroom.js has one and it's possible to opt out.

The scroll bouncing of chrome on desktop does not trigger the header.

Console Warnings

I think this might be due to the latest React update, as since updating I now get these warnings in my browser console:

Warning: ReactDOMComponent: Do not access .getDOMNode() of a DOM node; instead, use the node directly. This DOM node was rendered by `Headroom`.

.headroom--pinned doesn't get the right width with flexbox

I have a ul styled with flexbox inside headroom. When it is at the top of the page, it displays correctly (image 1). When it is in the .hearoom--pinned class, the flexbox doesn't seem to get the right width (image 2). When it is scrolled back up to the top of the page, it resets to the correct appearance (image 1 again).

screen shot 2016-09-17 at 10 12 00 am
screen shot 2016-09-17 at 10 12 10 am

Relevant Sass (this is happening on the mobile version):

.site-nav
  height: 40px
  margin-right: 12px
  padding-top: 6px
  ul
    display: flex
    flex-direction: row
    li
      list-style-type: none
      margin-left: 16px
      opacity: 0.5
      &:first-child
        margin-left: 0
      &:hover
        opacity: 1
  @media (max-width: $mobile)
    padding-top: 12px
    width: auto
    ul
      justify-content: space-between
      margin-left: 12px
      li
        margin-left: 0

should remove scroll listener(s) when unmounting

Scroll event listeners aren't cleaned up on unmounting. On a multipage app, where Headroom is used only on some pages, you get errors after it's been unmounted because you're attempting to alter state on a component that is no longer in the DOM.

(note the irony that I'm using your headroom component haha)

Corrupted content in the published version

There is some undesired and corrupted content in the currently published version (2.2.1).
Some files, which are named something like ..filename.un~ are, I guess, accidentally published to the npm repo.

See by yourself :

react-headroom
(noticed it when submitting this pull request)

Support manual pin/unpin

Add a prop to manually set pin/unpin state, e.g. to enable a hide button that unpins when pinned if user wants to hide headroom without scrolling down.

React.__spread warning in React 15

I know this is not an issue with react-headroom but an issue with coffee-react-transform. This is the only blocker that prevent me from using React 15. Do you have any plan to fix this ? I'd be happy to send a PR to convert this the codebase to ES6 and JSX.

Parent example

I can't find a clean way to implement the parent property.

In general the Headroom component is mounted before the any parent components and tries to access this.props.parent() immediately. A ref callback in any parent component gets called after Headroom has already called this.props.parent() (and therefore errors trying to addEventListener)

Does anyone have an example of how to use the parent property?

Won't work with react-snapshot

How to reproduce the bug :

Use this package and react-snapshot in a create-react-app app, then run yarn start.

Here is an example repository when this errors occurs : https://github.com/Ilshidur/nicolas-coutin.fr/tree/e37b48ec06d2ab2d2dde1e73c6fedc2a7106e4a5

Description of the bug :

An error is displayed :
addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component's render method, or you have multiple copies of React loaded (details: https://fb.me/react-refs-must-have-owner).

Preview of the bug :

Preview

Awesome package, by the way ! ๐Ÿ‘

Support of headroom--bottom

Hey, would it be possible to add the headroom-bottom class once the user scrolled to the bottom of the app, like with the raw headroom plugin? I could perhaps give it a try, if you're fine with that!

Unknown plugin "transform-undefined-to-void"

Running a project including the package throws an error with the newest (to date) parcel and yarn.
Building the project after running yarn fixes the problem

~> yarn add react-headroom
yarn add v1.3.2
[1/4] ๐Ÿ”  Resolving packages...
[2/4] ๐Ÿšš  Fetching packages...
[3/4] ๐Ÿ”—  Linking dependencies...
[4/4] ๐Ÿ“ƒ  Building fresh packages...
success Saved lockfile.
success Saved 7 new dependencies.
โ”œโ”€ [email protected]
โ”œโ”€ [email protected]
โ”œโ”€ [email protected]
โ”œโ”€ [email protected]
โ”œโ”€ [email protected]
โ”œโ”€ [email protected]
โ””โ”€ [email protected]
โœจ  Done in 3.47s.

Adding package doesn't throw error.

~> yarn start
yarn run v1.3.2
$ parcel src/index.html
Server running at http://localhost:1234
๐Ÿšจ  /Users/user/proj/project/node_modules/react-headroom/dist/index.js: Unknown plugin "transform-undefined-to-void" specified in "/Users/user/proj/project/node_modules/react-headroom/.babelrc" at 0, attempted to resolve relative to "/Users/user/proj/project/node_modules/react-headroom"
    at /Users/user/.config/yarn/global/node_modules/babel-core/lib/transformation/file/options/option-manager.js:180:17
    at Array.map (<anonymous>)
    at Function.normalisePlugins (/Users/user/.config/yarn/global/node_modules/babel-core/lib/transformation/file/options/option-manager.js:158:20)
    at OptionManager.mergeOptions (/Users/user/.config/yarn/global/node_modules/babel-core/lib/transformation/file/options/option-manager.js:234:36)
    at OptionManager.init (/Users/user/.config/yarn/global/node_modules/babel-core/lib/transformation/file/options/option-manager.js:368:12)
    at File.initOptions (/Users/user/.config/yarn/global/node_modules/babel-core/lib/transformation/file/index.js:212:65)
    at new File (/Users/user/.config/yarn/global/node_modules/babel-core/lib/transformation/file/index.js:135:24)
    at JSAsset.getParserOptions (/Users/user/.config/yarn/global/node_modules/parcel-bundler/src/assets/JSAsset.js:71:20)
    at <anonymous>
^C
~> cd node_modules/react-headroom/
~> cat package.json | grep transform
    "babel-plugin-transform-undefined-to-void": "^6.8.0",
~> yarn
yarn install v1.3.2
[1/4] ๐Ÿ”  Resolving packages...
[2/4] ๐Ÿšš  Fetching packages...
[3/4] ๐Ÿ”—  Linking dependencies...
warning " > [email protected]" has unmet peer dependency "webpack@1 || 2 || ^2.1.0-beta || ^2.2.0-rc".
warning " > [email protected]" has incorrect peer dependency "eslint-plugin-import@^1.16.0".
warning "eslint-config-airbnb > [email protected]" has incorrect peer dependency "eslint-plugin-import@^1.16.0".
[4/4] ๐Ÿ“ƒ  Building fresh packages...
โœจ  Done in 17.06s.
~> yarn build
yarn run v1.3.2
$ babel --copy-files src --out-dir dist
src/index.js -> dist/index.js
src/shouldUpdate.js -> dist/shouldUpdate.js
โœจ  Done in 0.90s.
~> cd -
/Users/user/proj/project
~> yarn start
yarn run v1.3.2
$ parcel src/index.html
Server running at http://localhost:1234
โœจ  Built in 3.38s.

onPin won't fire on page up.

So to reproduce this. You need to page down once and then page up.
I did some debugging and I think this is the part that is responsible for the issue

if currentScrollY <= 0 and
      state.state isnt "unfixed"
    return {
      action: "unfix"
      scrollDirection: scrollDirection
      distanceScrolled: distanceScrolled
    }

currentScrollY in this case is 0 and the whole condition is true and so the action would be unfixed. Not sure if there should be another action for bin in this case. But if you modified the condition to

if currentScrollY < 0 and
      state.state isnt "unfixed"
    return {
      action: "unfix"
      scrollDirection: scrollDirection
      distanceScrolled: distanceScrolled
    }

this won't satisfy the condition and it will fire the pin event

Set className on outer <div> instead

Is it possible if we set/expose the classnames in the outermost <div> (currently with className="headroom-wrapper") instead? That way we could use css adjacent or sibling selectors, e.g .headroom--pinned + .main, or .headroom--pinned ~ .footer.

Support partial visibility

Can we support partial visibility of the headroom contents at all time? So the header is always visible but expands/contracts to reveal more dynamically.

I tried implementing with a combination of custom styles and the pinStart attribute:

.headroom--unpinned {
  transform: translateY(-50%);
}

But the snap back to inline on scroll up occurs at the wrong position.

Keep headroom pinned when navigating to an internal link

When navigating to an internal link of a page (e.g. #something), I think that the headroom should always be shown until the scrolling ends. The reason behind this is that elements with IDs are usually positioned to accommodate a fixed header above themselves. Pinning the headroom during a programmatically invoked scroll would also improve consistency with the proposed non-JS mode (please see #125 for further details).

Also, in order to support smooth scrolling behavior, continuous inspection of window.pageYOffset is required. I wrote the following code snippet to solve the aforementioned problems:

const SCROLL_MAX_FRAMES_WITHOUT_PAGE_OFFSET_CHANGE = 30;

class Headroom extends React.Component {
  constructor() {
    // ...

    this.setState({
      downTolerance: this.props.downTolerance,
    });

    // Avoid problems with server-side rendering
    if (typeof window !== 'undefined') {
      // Keep headroom pinned during smooth scroll
      window.addEventListener('hashchange', () => {
        // Disable headroom unpinning caused by scrolling downwards
        this.setState({ downTolerance: Number.POSITIVE_INFINITY });
        this.headroom.pin();

        // Re-enable headroom unpinning after smooth scroll
        let prevPageYOffset = window.pageYOffset;
        let framesWithoutPageOffsetChange = 0;
        const checkScrollState = () => {
          // Check whether scrolling is still in progress
          if (window.pageYOffset !== prevPageYOffset) {
            prevPageYOffset = window.pageYOffset;
            framesWithoutPageOffsetChange = 0;
          } else {
            framesWithoutPageOffsetChange += 1;
            if (framesWithoutPageOffsetChange > SCROLL_MAX_FRAMES_WITHOUT_PAGE_OFFSET_CHANGE) {
              // Restore downTolerance of the headroom
              this.setState({ downTolerance: this.props.downTolerance });
              return;
            }
          }

          raf(checkScrollState);
        };

        raf(checkScrollState);
      });
    }
  }
}

A customized implementation of the snippet can be found here.

Inline height not recalculated on resize

React-headroom seems to force an inline style height on the headroom-wrapper even though disableInlineStyles is set to true. I'd be fine with this if the height would recalculate when resizing, but it doesn't.

The official version of headroom doesn't seem to do this on the demo site.

React 15.2.0 and unknown props issue

So... React 15.2.0 is out and I thought I would play with it and see all the issues that they were talking about for the last month or so.

According to this https://gist.github.com/jimfb/d99e0678e9da715ccf6454961ef04d1b, they need library maintainers to clean up their code.

Interestingly, the first library I got a warning about is yours (sorry)

I looked at the source code and I think this line is the one responsible for the warning
https://github.com/KyleAMathews/react-headroom/blob/master/src/index.js#L203

Not sure which properties should be excluded but I think the warning is clear enough for which properties to exclude when you render the div

Ideas?

Warnings with React 16.0.0

warning.js:33 Warning: React does not recognize the `calcHeightOnResize` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `calcheightonresize` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
    in div (created by Headroom)
    in div (created by Headroom)

You need to remove the unused properties from the div here.

initialState className

Hi,

First, thanks for your job, it's pretty cool :)

After reading src code I see that when state change to "unfixed" className is set to "headroom--unfixed", which is pretty cool for custom styling.
However in getInitialState state is to "unfixed" but className is to "headroom--pinned", this seems to be an issue and makes useless the "headroom--unfixed" class.

tiny white border when same color as hero

I'm trying to set-up Headroom on a landing w/ a hero image above the fold. My goal is to set the color of Headroom to the same color as image so it's indistinguishable until user starts scrolling.

So far, I can't seem to get rid of a tiny white border around Headroom.

I've replaced Headroom with a plain div of the same style properties, and that has no border, so I'm certain it's some feature of Headroom causing it.

Is this something I can style away?

// Headroom component

<Headroom
                    style={{
                        height: '65px',
                        background: '#6D83F9',
                    }}
                    >

                    <Link
                        to={prefixLink('/') }
                        style={{
                            color: 'black',
                            textDecoration: 'none',
                        }}
                        >
                        Gatsby!!!
                    </Link>
                </Headroom>

Things I've tried:

  • setting wrapperStyle to display: block, margin: 0, and some other low-hanging fruits
  • setting parent to display: flex, flexFlow: 'column nowrap' (following likely unrelated stackoverflow answer)

image

feature: add "top" class for when header is back at top

It would be great to add a class .headroom--top for when the header is initially pinned, but at the top.

This is beneficial for instances that the header should have specific styles when pinned, but not at the initial top position.

Semantically rename the wrapper `<div>`

Hi, great plugin btw. I have a sugeestion/idea/request

right now, this plugin renders

<div class="headroom-wrapper" > ... </div>

I would love to rename it by either props or whatever way you prefer to

<header class="headroom-wrapper" > ... </div>

in react, maybe add a tag prop so we can semantically rename the component if needed?
something like

<Headroom
  tag="header"
  ...
>

Thanks again for the great job and hope this gets implemented someday

Use PureComponent over PureRenderMixin

React 15.3.0 introduced PureComponent. The cool thing is that preact-compat supports that too now. So refactoring react-headroom to use that would get something that works with Preact as well.

Make it mobile-friendly

There perhaps should be a prop like disabled so users may set it to false based on media query or touch support. Sorry if it's there and I didn't notice.

Can i Use with reacrt-router-dom?

like

	<Headroom>
		<Navgitoin toggleVisibility={this.toggleVisibility.bind(this)} />
	</Headroom>
       <main>
	   <PageRouter />
       </main>

i try about it doesnt real work

it can hide and appear but just bit

GIF:

http://gph.is/2nCjhKI

Support other elements being source for scroll events

Sometimes you want to get scroll events from sources other than window e.g. an element with overflow.

Not sure how this would actually work in the react world. In the original headroom you just pass a ref to the element you want to listen to scroll events on when constructing the instance. Not as easy with react where you'd have to wait for the scroll source component to be mounted first.

Worth consideration anyway :)

React Headroom not working with Material UI (0.20.0) dialog

I am using react Headroom (^2.2.2) which is not working with React Matrial UI (0.20.0) dialog. Code is given below. Kindly have a look and let me know abut the issue. TIA

--MyPopup.js --

import React, { Component } from 'react';
import {withRouter} from 'react-router-dom';
import IconButton from 'material-ui/IconButton';
import Dialog from 'material-ui/Dialog';
import HeaderType2 from 'routes/common/HeaderType2';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import styles from '../style.scss';

const style = {
  dialogContentStyle:{
      width: '100%',
      maxWidth: 'none',
      padding:0,
      transform: 'translate(0, 0)'
  },
  dialogBodyStyle:{
      width: '100%',
      backgroundColor:'#eeeeee',
      padding:0,
      color:'black'
  },
  overlaystyle:{
    backgroundColor:'white',
    paddingTop:0
  }    
};

class MyPopup extends Component{ 
  state = {
    isPostCommentVisible:false    
  }

  postcomment = () => {    
    this.setState({isPostCommentVisible:true})
  }

  goBack = () =>{         
    if(this.state.isPostCommentVisible){
      this.setState({isPostCommentVisible:false})
    }   
  } 

  render() {   
    var that = this;    
    return(<MuiThemeProvider>
      <div> 
        <IconButton onClick={that.postcomment} iconClassName={`${styles.icons} ${styles.wm_icon_comment}`} iconStyle={style.iconStyle}  style={style.btnStyle} />       
        {
          (that.state.isPostCommentVisible)
          ?
          <Dialog contentStyle={style.dialogContentStyle} style={style.overlaystyle} overlayStyle={{backgroundColor:'transparent'}} bodyStyle={style.dialogBodyStyle} paperClassName={`${styles.boxShadowNone}`} bodyClassName={`${styles.bodyClassName}`} autoScrollBodyContent={true} repositionOnUpdate={false} open={that.state.isPostCommentVisible} modal={true}>

            <HeaderType2 styles={styles} title={"Offers and Questions"} goBack={this.goBack} />
            
            ... code ....
            ... code ....
            ... code ....
            ... code ....
            
          </Dialog>
          :
          null
        }
        
      </div>
    </MuiThemeProvider>);
   
  }
}

export default withRouter(MyPopup);

--HeaderType2.js--

import React, { Component } from 'react';
import Headroom from 'react-headroom';
import {withRouter} from 'react-router-dom';

import styles from './style.scss';

class HeaderType2 extends Component { 

  state={
      headroomStyleTranslateY:"translateY(0%)"
    }   

  onPin=() =>{
    this.setState({headroomStyleTranslateY:'translateY(0%)'});        
  }

  onUnpin=() =>{
    this.setState({headroomStyleTranslateY:'translateY(-100%)'});        
  }

  onUnfix=() =>{    
    this.setState({headroomStyleTranslateY:'translateY(0%)'});    
  }

  render() {
    var that = this;
    var headroomStyle = function() {
      return(
        {   
          transform:that.state.headroomStyleTranslateY,
          WebkitTransition: 'all .5s ease-in-out', 
          MozTransition: 'all .5s ease-in-out',
          OTransition: 'all .5s ease-in-out', 
          transition: 'all .5s ease-in-out',
          position:'fixed',
          width:'100%',
          top:0,
          zIndex:2
          
        }
      )
    }

    return (<Headroom pinStart={5} upTolerance={10} disableInlineStyles={true} wrapperStyle={{zIndex:2}} style={headroomStyle()} onPin={that.onPin} onUnpin={that.onUnpin} onUnfix={that.onUnfix}>
      <div className={styles.container}>
         ... code ....
         ... code ....
         ... code ....
      </div>
    </Headroom>);
  }
}

export default withRouter(HeaderType2);

Note on 1.8.3

Could you create release notes on v1.8.3 that you've upgraded to React 15?

My client app uses 0.14.x and it wasn't clear which release version I needed to use (had to parse through the package.json history).

Typo

In the readme, "npm install react-headrooom" should be "npm install react-headroom".

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.