ldx-widgets
Version:
widgets
175 lines (150 loc) • 5.63 kB
JavaScript
(function() {
var Pvr, React, SelectPvr, SelectPvrOption, _, animationMixin, div;
React = require('react');
_ = require('lodash');
animationMixin = require('../mixins/animation_mixin');
Pvr = React.createFactory(require('./pvr'));
SelectPvrOption = React.createFactory(require('./select_pvr_option'));
div = React.DOM.div;
/*
Select Popover Props
@props.options
array of objects containing at minimum a label and value attribute
optionally a subLabel property can be passed
@props.defaultSelected
value of the option selected by default
@props.close - func that closes the popover
@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.onChange
method to call when the non selected option is clicked
@props.hideSelected
when on, the defaultSelected option will be removed from the list
@props.optionHeight
the height of the options in the list
@props.headerTitle
optional title String for popover header
@props.headerClass
optional class for popover header
@props.noWrapOptions
option to turn off text wrapping on the menu's options
@props.maxHeight
the maximum height the popover should be. used to set height on the pvr if this is
lower than the computed height.
@props.pvrProps
properties germane to PVR wrapper: width, height, anchor, hAdjust, vAdjust, direction
@props.canDeselect
option to de-select the selected option - will allow us call handle click for the selected option
*/
SelectPvr = React.createClass({
displayName: 'SelectPvr',
mixins: [animationMixin],
enterStateStart: {
scale: .9
},
enterStateEnd: {
scale: 1
},
enterEasing: 'easeOutElastic',
enterDuration: 600,
propTypes: {
close: React.PropTypes.func.isRequired
},
getDefaultProps: function() {
return {
options: [],
styleMixin: {},
headerTitle: null,
headerClass: '',
onChange: function() {},
hideSelected: false,
optionHeight: 36,
noWrapOptions: false,
pvrProps: {},
canDeselect: false
};
},
render: function() {
var canDeselect, className, close, disabled, headerClass, headerTitle, height, hideSelected, i, len, maxHeight, noWrapOptions, option, optionEls, optionHeight, options, optionsEqual, pvrProps, ref, ref1, ref2, scale, selectedOption, style, styleMixin;
ref = this.props, styleMixin = ref.styleMixin, options = ref.options, hideSelected = ref.hideSelected, optionHeight = ref.optionHeight, headerTitle = ref.headerTitle, headerClass = ref.headerClass, noWrapOptions = ref.noWrapOptions, disabled = ref.disabled, className = ref.className, maxHeight = ref.maxHeight, close = ref.close, canDeselect = ref.canDeselect;
ref1 = this.state, selectedOption = ref1.selectedOption, scale = ref1.scale;
style = {};
pvrProps = _.cloneDeep(this.props.pvrProps);
this.hasHeader = headerTitle != null;
if (height === 'auto') {
height = options.length * optionHeight + (options.length - 1) - (hideSelected ? optionHeight : 0);
}
if (pvrProps.height == null) {
pvrProps.height = options.length * optionHeight + (options.length - 1) - (hideSelected ? optionHeight : 0);
}
if (this.hasHeader) {
pvrProps.height += 34;
}
if ((maxHeight != null) && pvrProps.height > maxHeight) {
pvrProps.height = maxHeight;
}
_.assign(style, styleMixin);
if (((ref2 = pvrProps.styleMixin) != null ? ref2.maxHeight : void 0) != null) {
style.maxHeight = pvrProps.styleMixin.maxHeight;
}
style.height = pvrProps.height;
if (pvrProps.width) {
style.width = pvrProps.width;
}
optionEls = [];
for (i = 0, len = options.length; i < len; i++) {
option = options[i];
optionsEqual = (function() {
if (typeof selectedOption === 'string') {
return selectedOption === option.label;
} else if (typeof selectedOption === 'object') {
return _.isEqual(selectedOption, option);
}
})();
if (hideSelected && optionsEqual) {
continue;
}
optionEls.push(SelectPvrOption({
hasSubLabel: option.subLabel != null,
option: option,
optionHeight: optionHeight,
key: option.id || option.value,
isSelected: optionsEqual,
canDeselect: canDeselect,
handleClick: this.handleClick,
noWrapOptions: noWrapOptions
}));
}
pvrProps.scale = scale;
pvrProps.close = close;
pvrProps.element = div({
key: 'select-pvr',
className: 'select-pvr',
style: style
}, [
this.hasHeader ? div({
key: 'header',
className: "header plain-pvr-content-item " + headerClass
}, headerTitle) : void 0, div({
key: 'inner-rows'
}, optionEls)
]);
return Pvr(pvrProps);
},
getInitialState: function() {
return {
selectedOption: this.props.defaultSelected || null
};
},
handleClick: function(option) {
this.setState({
selectedOption: option
});
this.props.onChange(option);
return this.props.close();
}
});
module.exports = SelectPvr;
}).call(this);