Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Schmidt committed May 2, 2017
0 parents commit f6f4884
Show file tree
Hide file tree
Showing 14 changed files with 5,148 additions and 0 deletions.
9 changes: 9 additions & 0 deletions .editorconfig
@@ -0,0 +1,9 @@
# http://EditorConfig.org
# top-most EditorConfig file
root = true

[*]
end_of_line = lf
insert_final_newline = false
indent_style = space
indent_size = 2
9 changes: 9 additions & 0 deletions .eslintignore
@@ -0,0 +1,9 @@
# Ignore snapshots
*.snap

# Ignore dist
dist/**
lib/**

# Ignore webpack
webpack.config.js
105 changes: 105 additions & 0 deletions .gitattributes
@@ -0,0 +1,105 @@
# From https://github.com/Danimoth/gitattributes/blob/master/Web.gitattributes

# Handle line endings automatically for files detected as text
# and leave all files detected as binary untouched.
* text=auto

#
# The above will handle all files NOT found below
#

#
## These files are text and should be normalized (Convert crlf => lf)
#

# source code
*.php text
*.css text
*.sass text
*.scss text
*.less text
*.styl text
*.js text eol=lf
*.coffee text
*.json text
*.htm text
*.html text
*.xml text
*.svg text
*.txt text
*.ini text
*.inc text
*.pl text
*.rb text
*.py text
*.scm text
*.sql text
*.sh text
*.bat text

# templates
*.ejs text
*.hbt text
*.jade text
*.haml text
*.hbs text
*.dot text
*.tmpl text
*.phtml text

# server config
.htaccess text

# git config
.gitattributes text
.gitignore text
.gitconfig text

# code analysis config
.eslintignore text

# misc config
*.yaml text
*.yml text
.editorconfig text

# build config
*.npmignore text
*.bowerrc text

# Heroku
Procfile text
.slugignore text

# Documentation
*.md text
LICENSE text
AUTHORS text

# Yarn
yarn.lock text

#
## These files are binary and should be left untouched
#

# (binary is a macro for -text -diff)
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.mov binary
*.mp4 binary
*.mp3 binary
*.flv binary
*.fla binary
*.swf binary
*.gz binary
*.zip binary
*.7z binary
*.ttf binary
*.eot binary
*.woff binary
*.pyc binary
*.pdf binary
16 changes: 16 additions & 0 deletions .gitignore
@@ -0,0 +1,16 @@
.vscode
.cache
node_modules
reports
dist
dist-storybook
.bin/
nuget
npm-debug.log*
.DS_store
.eslintcache
.stylelintcache
.idea
.tern
.tmp
*.log
Empty file added .storybook/base.css
Empty file.
14 changes: 14 additions & 0 deletions .storybook/config.js
@@ -0,0 +1,14 @@
import React from 'react'
import { configure } from '@kadira/storybook'
import './base.css'

/**
* Use require.context to load dynamically: https://webpack.github.io/docs/context.html
*/
const req = require.context('../stories', true, /story\.js$/)

function loadStories() {
req.keys().forEach(req)
}

configure(loadStories, module)
64 changes: 64 additions & 0 deletions package.json
@@ -0,0 +1,64 @@
{
"name": "react-intersection-observer",
"version": "0.1.0",
"description": "Monitor if a component is inside the viewport, using IntersectionObserver API",
"main": "index.js",
"author": "Daniel Schmidt",
"license": "MIT",
"scripts": {
"lint": "eslint src/.",
"precommit": "lint-staged",
"pretty": "prettier '{src,tests}/**/*.js' --write --no-semi --single-quote --trailing-comma all"
},
"lint-staged": {
"*.js": [
"prettier --write --no-semi --single-quote --trailing-comma all",
"eslint",
"git add"
]
},
"babel": {
"presets": [
"react-app"
]
},
"eslintConfig": {
"extends": [
"insilico",
"prettier",
"prettier/react"
]
},
"jest": {
"testEnvironment": "jsdom",
"snapshotSerializers": [
"<rootDir>/node_modules/enzyme-to-json/serializer"
]
},
"dependencies": {
"enzyme-to-json": "1.5.1",
"intersection-observer": "0.2.1"
},
"peerDependencies": {
"prop-types": "^15.5.8",
"react": "^0.14.0 || ^15.0.0"
},
"devDependencies": {
"babel-cli": "6.24.1",
"babel-core": "6.24.1",
"babel-jest": "19.0.0",
"babel-preset-react-app": "2.2.0",
"enzyme": "2.8.2",
"eslint": "3.19.0",
"eslint-config-insilico": "2.1.5",
"eslint-config-prettier": "1.7.0",
"husky": "0.13.3",
"jest": "19.0.2",
"lint-staged": "3.4.1",
"prettier": "1.2.2",
"prop-types": "15.5.8",
"react": "15.5.4",
"react-dom": "15.5.4",
"react-test-renderer": "15.5.4"
}
}
100 changes: 100 additions & 0 deletions src/Observer.js
@@ -0,0 +1,100 @@
import React, { Component, createElement } from 'react' // eslint-disable-line no-unused-vars
import PropTypes from 'prop-types'
import { observe, unobserve } from './intersection'

const isFunction = func => typeof func === 'function'

/**
* Monitors scroll, and triggers the children function with updated props
*
<Observer>
{inView => (
<h1>{`${inView}`}</h1>
)}
</Observer>
*/
class Observer extends Component {
static propTypes = {
/** Element tag to use for the wrapping */
tag: PropTypes.node,
/** Children should be either a function or a node */
children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
/** Only trigger this method once */
triggerOnce: PropTypes.bool,
/** Number between 0 and 1 indicating the the percentage that should be visible before triggering */
threshold: PropTypes.number,
/** Call this function whenever the in view state changes */
onChange: PropTypes.func,
/** Use render method to only render content when inView */
render: PropTypes.func,
}

static defaultProps = {
tag: 'div',
threshold: 0,
triggerOnce: false,
}

state = {
inView: false,
}

componentWillUpdate(nextProps, nextState) {
if (!!this.props.onChange && nextState.inView !== this.state.inView) {
this.props.onChange(nextState.inView)
}
}

componentWillUnmount() {
if (this.node) {
unobserve(this.node)
this.node = null
}
}

node = null

handleNode = node => {
if (this.node) unobserve(this.node)
if (node) {
observe(
node,
this.handleChange,
this.props.triggerOnce,
this.props.threshold,
)
}
this.node = node
}

handleChange = inView => {
this.setState({ inView })
}

render() {
const {
children,
render,
tag,
triggerOnce,
threshold,
...props
} = this.props
const { inView } = this.state

return createElement(
tag,
{
...props,
ref: this.handleNode,
},
// If render is a function, use it to render content when in view
inView && isFunction(render) ? render() : null,
// If children is a function, render it with the current inView status.
// Otherwise always render children. Assume onChange is being used outside, to control the the state of children.
isFunction(children) ? children(inView) : children,
)
}
}

export default Observer

0 comments on commit f6f4884

Please sign in to comment.