-
Notifications
You must be signed in to change notification settings - Fork 12
/
XBlock.jsx
65 lines (56 loc) · 2.14 KB
/
XBlock.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import React from "react";
import { isServer } from "../utils/index.jsx";
/**
* XBlock represents the grid cell (div). Do not apply custom styling and margins on this block.
*/
export default class XBlock extends React.Component {
// static propTypes = {
// width: React.PropTypes.number
// };
static defaultProps = {
width: 1,
measured: false
};
static defaultStyle = {
position: isServer ? undefined : `absolute`,
boxSizing: `border-box`
};
/**
* Reference to the div element.
* @type {HTMLElement|null}
*/
divElement = null;
/**
* Identifies whether this .xblock is initialized.
* @type {boolean}
*/
placed = false;
componentDidUpdate () {
if (this.placed || !this.props.parent || this.props["data-xkey"])
return;
this.placed = true;
const parent = this.props.parent;
requestAnimationFrame(() => { if (!this.divElement) return;
let images = Array.prototype.slice.call(this.divElement.querySelectorAll(`img`)),
handleImages = images.length > 0 && parent.props.updateOnImagesLoad;
if (handleImages) images.forEach(
(img) => !img.complete && img.addEventListener(`load`, parent.update)
);
if (this.props.height !== this.divElement.clientHeight)
parent.update(); // useful when f.e. image was loaded in between renders
});
}
render () {
const { width, height, measured, parent, style, ...rest } = this.props,
maxColumns = this.props.parent.columns,
columns = Math.min(width || 1, maxColumns, this.props.parent.props.maxColumns);
style.width = Math.floor(columns * this.props.parent.containerWidth / maxColumns);
return <div data-width={ columns }
{ ...rest }
style={ { ...style, ...XBlock.defaultStyle } }
className={ measured ? `xblock` : (isServer ? `xblock xblock-static` : ``) }
ref = { (x) => this.divElement = x }>
{ this.props.children }
</div>;
}
}