|
1 |
| -import React, {Component} from 'react'; |
| 1 | +import React from 'react'; |
2 | 2 | import { findDOMNode } from 'react-dom';
|
3 | 3 |
|
4 | 4 | export const defaultRect = { top: 0, bottom: 0, left: 0, right: 0, width: 0, height: 0 };
|
5 | 5 | const identity = x => x;
|
6 | 6 |
|
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 } |
11 | 12 |
|
12 |
| - static defaultProps = { formulas: [identity], component: 'div' } |
| 13 | + static defaultProps = { formulas: [identity], component } |
13 | 14 |
|
14 |
| - constructor(props) { |
15 |
| - super(props); |
| 15 | + constructor(props) { |
| 16 | + super(props); |
16 | 17 |
|
17 |
| - const self = this; |
| 18 | + const self = this; |
18 | 19 |
|
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 } |
21 | 22 |
|
22 |
| - render() { |
23 |
| - const {ref = props.ref || identity} = this.props; |
| 23 | + render() { |
| 24 | + const {ref = self.props.ref || identity} = this.props; |
24 | 25 |
|
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 | + } |
29 | 31 | }
|
| 32 | + this.state = {}; |
30 | 33 | }
|
31 |
| - this.state = {}; |
32 |
| - } |
33 | 34 |
|
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 | + } |
39 | 40 |
|
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 | + } |
44 | 46 | }
|
45 | 47 | }
|
46 | 48 |
|
47 |
| -export class TrackDocument extends Component { |
| 49 | +export const Track = createInjector('div'); |
| 50 | + |
| 51 | +export class TrackDocument extends React.Component { |
48 | 52 | static propTypes = { children: React.PropTypes.func.isRequired,
|
49 | 53 | formulas: React.PropTypes.array }
|
50 | 54 |
|
@@ -76,30 +80,37 @@ export class TrackDocument extends Component {
|
76 | 80 | }
|
77 | 81 | }
|
78 | 82 |
|
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]) } |
84 | 89 |
|
85 |
| - static defaultProps = { formulas: [identity], component: 'div' } |
| 90 | + static defaultProps = { formulas: [identity], component } |
86 | 91 |
|
87 |
| - constructor(props) { |
88 |
| - super(props); |
89 |
| - this.state = {}; |
90 |
| - } |
| 92 | + constructor(props) { |
| 93 | + super(props); |
| 94 | + this.state = {}; |
| 95 | + } |
91 | 96 |
|
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 | + } |
97 | 102 |
|
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 | + } |
104 | 113 | }
|
105 | 114 | }
|
| 115 | + |
| 116 | +export const TrackedDiv = createTrackedComponent('div'); |
0 commit comments