Skip to content

Commit 22f59a0

Browse files
committed
createTrackedComponent, createInjector
1 parent bd7fd51 commit 22f59a0

File tree

2 files changed

+66
-55
lines changed

2 files changed

+66
-55
lines changed

examples/demo/app.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ class App extends Component {
4343
alt="Fork me on GitHub"
4444
dataCanonicalSrc="https://s3.amazonaws.com/github/ribbons/forkme_right_green_007200.png" /></a>
4545

46-
<TrackedDiv className="hero" formulas={[topTop]}>
47-
{ (posTopTop) =>
48-
<div>
46+
<Track className="hero" formulas={[topTop]}>
47+
{ (Div, posTopTop) =>
48+
<Div>
4949
<a href="https://github.com/gilbox/react-track">
5050
<h1
5151
style={tween(scrollY, {
@@ -75,8 +75,8 @@ class App extends Component {
7575
[posTopTop]: {opacity: 1, transform: translate3d(0,0,0)},
7676
[posTopTop+200]: {opacity: 0, transform: translate3d(0,-150,0)}
7777
})}>v</div>
78-
</div>
79-
}</TrackedDiv>
78+
</Div>
79+
}</Track>
8080

8181
{/* fade */}
8282
<Track component="h2" formulas={[topBottom, centerCenter]}>

src/index.js

Lines changed: 61 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,54 @@
1-
import React, {Component} from 'react';
1+
import React from 'react';
22
import { findDOMNode } from 'react-dom';
33

44
export const defaultRect = { top: 0, bottom: 0, left: 0, right: 0, width: 0, height: 0 };
55
const identity = x => x;
66

7-
export class Track extends Component {
8-
static propTypes = { ref: React.PropTypes.func,
9-
children: React.PropTypes.func.isRequired,
10-
formulas: React.PropTypes.array }
7+
export function createInjector(component) {
8+
return class Track extends React.Component {
9+
static propTypes = { ref: React.PropTypes.func,
10+
children: React.PropTypes.func.isRequired,
11+
formulas: React.PropTypes.array }
1112

12-
static defaultProps = { formulas: [identity], component: 'div' }
13+
static defaultProps = { formulas: [identity], component }
1314

14-
constructor(props) {
15-
super(props);
15+
constructor(props) {
16+
super(props);
1617

17-
const self = this;
18+
const self = this;
1819

19-
this.DecoratedComponent = class extends Component {
20-
static propTypes = { ref: React.PropTypes.func }
20+
this.DecoratedComponent = class extends React.Component {
21+
static propTypes = { ref: React.PropTypes.func }
2122

22-
render() {
23-
const {ref = props.ref || identity} = this.props;
23+
render() {
24+
const {ref = self.props.ref || identity} = this.props;
2425

25-
return <props.component
26-
{...props}
27-
{...this.props}
28-
ref={r => ref(self.nodeRef = r)} />
26+
return <props.component
27+
{...self.props}
28+
{...this.props}
29+
ref={r => ref(self.nodeRef = r)} />
30+
}
2931
}
32+
this.state = {};
3033
}
31-
this.state = {};
32-
}
3334

34-
componentWillReceiveProps() {
35-
const node = findDOMNode(this.nodeRef);
36-
const rect = node.getBoundingClientRect();
37-
this.setState({rect, node});
38-
}
35+
componentWillReceiveProps() {
36+
const node = findDOMNode(this.nodeRef);
37+
const rect = node.getBoundingClientRect();
38+
this.setState({rect, node});
39+
}
3940

40-
render() {
41-
const {rect=defaultRect, node={}} = this.state;
42-
return this.props.children(this.DecoratedComponent,
43-
...this.props.formulas.map(formula => formula(rect, node)));
41+
render() {
42+
const {rect=defaultRect, node={}} = this.state;
43+
return this.props.children(this.DecoratedComponent,
44+
...this.props.formulas.map(formula => formula(rect, node)));
45+
}
4446
}
4547
}
4648

47-
export class TrackDocument extends Component {
49+
export const Track = createInjector('div');
50+
51+
export class TrackDocument extends React.Component {
4852
static propTypes = { children: React.PropTypes.func.isRequired,
4953
formulas: React.PropTypes.array }
5054

@@ -76,30 +80,37 @@ export class TrackDocument extends Component {
7680
}
7781
}
7882

79-
export class TrackedDiv extends Component {
80-
static propTypes = { children: React.PropTypes.func.isRequired,
81-
formulas: React.PropTypes.array,
82-
component: React.PropTypes.oneOfType([React.PropTypes.element,
83-
React.PropTypes.string]) }
83+
export function createTrackedComponent(component) {
84+
return class Tracked extends React.Component {
85+
static propTypes = { children: React.PropTypes.func.isRequired,
86+
formulas: React.PropTypes.array,
87+
component: React.PropTypes.oneOfType([React.PropTypes.element,
88+
React.PropTypes.string]) }
8489

85-
static defaultProps = { formulas: [identity], component: 'div' }
90+
static defaultProps = { formulas: [identity], component }
8691

87-
constructor(props) {
88-
super(props);
89-
this.state = {};
90-
}
92+
constructor(props) {
93+
super(props);
94+
this.state = {};
95+
}
9196

92-
componentWillReceiveProps() {
93-
const node = findDOMNode(this.div);
94-
const rect = node.getBoundingClientRect();
95-
this.setState({rect, node});
96-
}
97+
componentWillReceiveProps() {
98+
const node = findDOMNode(this.nodeRef);
99+
const rect = node.getBoundingClientRect();
100+
this.setState({rect, node});
101+
}
97102

98-
render() {
99-
const {rect=defaultRect, node={}} = this.state;
100-
const {component:Comp} = this.props;
101-
return <Comp ref={r => this.div = r} {...this.props}>
102-
{this.props.children(...this.props.formulas.map(formula => formula(rect, node)))}
103-
</Comp>;
103+
render() {
104+
const {rect=defaultRect, node={}} = this.state;
105+
const {props} = this;
106+
107+
return (
108+
<props.component ref={r => this.nodeRef = r} {...props}>
109+
{props.children(...props.formulas.map(formula => formula(rect, node)))}
110+
</props.component>
111+
);
112+
}
104113
}
105114
}
115+
116+
export const TrackedDiv = createTrackedComponent('div');

0 commit comments

Comments
 (0)