UNPKG

ldx-widgets

Version:

widgets

223 lines (199 loc) 8.05 kB
(function() { var PropTypes, Pvr, React, SelectPvr, SelectPvrOption, _, animationMixin, createClass, div; React = require('react'); PropTypes = require('prop-types'); createClass = require('create-react-class'); _ = require('lodash'); animationMixin = require('../mixins/animation_mixin'); Pvr = React.createFactory(require('./pvr')); SelectPvrOption = React.createFactory(require('./select_pvr_option')); div = React.DOM.div; /*& @general Select popover menu with sub-option capability @props.options - [Array] - Required array of objects containing at minimum a label and value attribute optionally a subLabel property can be passed @props.defaultSelected - [Object|String] - Optional value of the option selected by default @props.close - [Function] - Required func that closes the popover @props.styleMixin - [Object] - Optional 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 - [Function] - Required method to call when the non selected option is clicked @props.hideSelected - [Boolean] - Optional when on, the defaultSelected option will be removed from the list @props.headerTitle - [String] - Optional optional title String for popover header @props.headerClass - [String] - Optional optional class for popover header @props.maxHeight - [Number] - Optional the maximum height the popover should be. used to set height on the pvr if this is lower than the computed height. @props.pvrProps - [Object] - Optional properties germane to PVR wrapper: width, height, anchor, hAdjust, vAdjust, direction & */ SelectPvr = createClass({ displayName: 'SelectPvr', mixins: [animationMixin], enterStateStart: { scale: .9 }, enterStateEnd: { scale: 1 }, enterEasing: 'easeOutElastic', enterDuration: 600, propTypes: { options: PropTypes.array.isRequired, styleMixin: PropTypes.object, headerClass: PropTypes.string, close: PropTypes.func.isRequired, optionHeight: PropTypes.number, onChange: PropTypes.func.isRequired, maxHeight: PropTypes.number, pvrProps: PropTypes.object, canDeselect: PropTypes.bool, noWrapOptions: PropTypes.bool, defaultSelected: PropTypes.oneOfType([PropTypes.string, PropTypes.object]) }, getInitialState: function() { var defaultSelected, optionHeight, options, ref; ref = this.props, defaultSelected = ref.defaultSelected, options = ref.options, optionHeight = ref.optionHeight; return { selectedOption: defaultSelected || null, aggregateOptionsHeight: options.length * optionHeight + options.length * 1, openSubOptions: null }; }, getDefaultProps: function() { return { options: [], styleMixin: {}, headerTitle: null, headerClass: '', hideSelected: false, optionHeight: 36, noWrapOptions: false, pvrProps: {}, canDeselect: false }; }, render: function() { var aggregateOptionsHeight, canDeselect, childItems, children, chld, className, close, disabled, headerClass, headerTitle, hideSelected, i, id, j, label, len, len1, maxHeight, noWrapOptions, openSubOptions, opth, option, optionEls, optionHeight, options, optionsEqual, pvrProps, ref, ref1, ref2, scale, selectedOption, style, styleMixin, subLabel, subOptionsHeight, value; 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, aggregateOptionsHeight = ref1.aggregateOptionsHeight, openSubOptions = ref1.openSubOptions; style = {}; pvrProps = _.cloneDeep(this.props.pvrProps); this.hasHeader = headerTitle != null; if (pvrProps.height == null) { pvrProps.height = aggregateOptionsHeight - (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]; children = option.children, label = option.label, id = option.id, value = option.value, subLabel = option.subLabel; optionsEqual = this.compareOptions(option); if (hideSelected && optionsEqual) { continue; } childItems = []; subOptionsHeight = 0; if (children != null) { for (j = 0, len1 = children.length; j < len1; j++) { chld = children[j]; if (!(chld != null)) { continue; } opth = chld.optionHeight || optionHeight; subOptionsHeight += opth; childItems.push(SelectPvrOption({ key: chld.id || chld.value, hasSubLabel: chld.subLabel != null, option: chld, optionHeight: opth, isSelected: this.compareOptions(chld), canDeselect: chld.canDeselect, handleChange: chld.handleChange || this.handleChange, noWrapOptions: chld.noWrapOptions, customClass: chld.customClass })); } } optionEls.push(SelectPvrOption({ hasSubLabel: subLabel != null, option: option, optionHeight: optionHeight, key: id || value, isSelected: optionsEqual, canDeselect: canDeselect, handleChange: this.handleChange, noWrapOptions: noWrapOptions, subOptionsHeight: subOptionsHeight, setOpenSubOptions: this.setOpenSubOptions, isOpen: childItems.length && openSubOptions === option }, childItems)); } 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); }, handleChange: function(option) { this.setState({ selectedOption: option }); this.props.onChange(option); return this.props.close(); }, setOpenSubOptions: function(option, adjust) { var agg, optionHeight, options, ref; ref = this.props, options = ref.options, optionHeight = ref.optionHeight; agg = options.length * optionHeight + (options.length * 1) + adjust; return this.setState({ openSubOptions: option, aggregateOptionsHeight: agg }); }, compareOptions: function(option) { var label, selectedOption; selectedOption = this.state.selectedOption; label = option.label; if (typeof selectedOption === 'string') { return selectedOption === label; } else if (typeof selectedOption === 'object') { return _.isEqual(selectedOption, option); } } }); module.exports = SelectPvr; }).call(this);