ldx-widgets
Version:
widgets
184 lines (164 loc) • 5.43 kB
JavaScript
(function() {
var Flux, PvrContentItem, PvrWrapper, React, _, div;
React = require('react');
_ = require('lodash');
Flux = require('delorean').Flux;
PvrContentItem = React.createFactory(require('./pvr_content'));
div = React.DOM.div;
/*
Popover Props
@props.items
array of objects containing at minimum a label and value attribute
optionally a subLabel property can be passed
@props.height
height of the pvr, 'auto' and it will grow to size of list
@props.width
width of the pvr
@props.styleMixin
object containing any style properties to mixin with and/or overrride the defaults
note that width height are passed separately so they can have defaults and auto settings
passing widt/height in this object could cause issues
@props.optionHeight
the height of each item row
@props.element
pass e.currentTarget element through to enable auto-positioning
if this isn't passed, you'll have to manually configure positioning with styleMixin or CSS
@props.offsetTop
set a value to add to the auto-calculated top value for custom positioning
@props.offsetLeft
set a value to add to the auto-calculated left value for custom positioning
@props.headerTitle
optional title String for popover header
*/
PvrWrapper = React.createClass({
displayName: 'PvrWrapper',
mixins: [Flux.mixins.storeListener],
watchStores: ['popoverModal'],
getDefaultProps: function() {
return {
options: [],
width: 250,
styleMixin: {},
hideSelected: false,
itemHeight: 30,
position: 'bottom',
offsetTop: 0,
offsetLeft: 0,
showNib: true
};
},
componentWillMount: function() {
return window.addEventListener("resize", this.updateDimensions);
},
componentDidMount: function() {
return this.setState({
height: this.refs.inner.clientHeight
});
},
getInitialState: function() {
return {
height: 'auto'
};
},
componentWillUnmount: function() {
return window.removeEventListener("resize", this.updateDimensions);
},
updateDimensions: function() {
return this.forceUpdate();
},
render: function() {
var calcLeft, elPos, element, headerTitle, height, i, item, itemHeight, itemRows, items, left, leftAdjust, len, nibClass, nibLeft, offsetLeft, offsetTop, position, ref, showNib, style, styleMixin, width;
height = this.state.height;
ref = this.props, width = ref.width, styleMixin = ref.styleMixin, items = ref.items, itemHeight = ref.itemHeight, position = ref.position, element = ref.element, offsetTop = ref.offsetTop, offsetLeft = ref.offsetLeft, headerTitle = ref.headerTitle, showNib = ref.showNib;
this.hasHeader = headerTitle != null;
if (items != null) {
if (height === 'auto') {
height = items.length * itemHeight + (items.length - 1);
}
}
if (this.hasHeader) {
height += 34;
}
elPos = element ? element.getBoundingClientRect() : {};
style = {
height: height + 20,
width: width,
top: (elPos.top || 0) + offsetTop,
left: (elPos.left || 0) + offsetLeft
};
if (element) {
left = (function() {
if (width < element.clientWidth) {
return (element.clientWidth - width) / 2;
} else if (width > element.clientWidth) {
return -((width / 2) - (element.clientWidth / 2));
} else {
return 0;
}
})();
calcLeft = elPos.left + offsetLeft;
if (width + calcLeft > window.outerWidth) {
leftAdjust = window.outerWidth - (width + calcLeft);
style.left += leftAdjust;
}
if (calcLeft < 0) {
leftAdjust = calcLeft;
style.left = 8;
}
nibLeft = (element.clientWidth / 2) + Math.abs(leftAdjust);
switch (position) {
case 'bottom':
style.top += element.clientHeight + 5;
style.left += left;
}
}
_.assign(style, styleMixin);
itemRows = [];
if (items != null) {
for (i = 0, len = items.length; i < len; i++) {
item = items[i];
itemRows.push(PvrContentItem({
hasSubLabel: item.subLabel != null,
item: item,
itemHeight: itemHeight,
key: item.key
}));
}
}
if (itemRows.length === 0) {
itemRows = div({
className: 'no-items'
}, t('No information to display'));
}
nibClass = "nib";
if (this.hasHeader) {
nibClass += " headerNib";
}
return div({
className: "plain-pvr " + position,
style: style
}, [
showNib ? div({
key: 'nib',
className: nibClass,
style: {
left: nibLeft || '50%'
}
}) : void 0, div({
key: 'inner',
className: 'inner'
}, [
this.hasHeader ? div({
key: 'header',
className: 'header plain-pvr-content-item'
}, headerTitle) : void 0, div({
key: 'inner-rows',
className: 'inner-rows',
ref: 'inner'
}, itemRows)
])
]);
}
});
module.exports = PvrWrapper;
}).call(this);