ldx-widgets
Version:
widgets
171 lines (125 loc) • 4.26 kB
text/coffeescript
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
###
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: ->
{
options: []
styleMixin: {}
headerTitle: null
headerClass: ''
onChange: ->
hideSelected: no
optionHeight: 36
noWrapOptions: no
pvrProps: {}
canDeselect: no
}
render: ->
{styleMixin, options, hideSelected, optionHeight, headerTitle, headerClass, noWrapOptions, disabled, className, maxHeight, close, canDeselect} = @props
{selectedOption, scale} = @state
style = {}
pvrProps = _.cloneDeep @props.pvrProps
@hasHeader = headerTitle?
height = options.length * optionHeight + (options.length - 1) - (if hideSelected then optionHeight else 0) if height is 'auto'
unless pvrProps.height?
pvrProps.height = options.length * optionHeight + (options.length - 1) - (if hideSelected then optionHeight else 0)
if @hasHeader
pvrProps.height += 34
if maxHeight? and pvrProps.height > maxHeight
pvrProps.height = maxHeight
_.assign style, styleMixin
style.height = pvrProps.height
if pvrProps.width
style.width = pvrProps.width
optionEls = []
for option in options
optionsEqual = (->
if typeof selectedOption is 'string' then selectedOption is option.label
else if typeof selectedOption is 'object' then _.isEqual(selectedOption, option)
)()
continue if hideSelected and optionsEqual
optionEls.push SelectPvrOption {
hasSubLabel: option.subLabel?
option: option
optionHeight: optionHeight
key: option.id or option.value
isSelected: optionsEqual
canDeselect: canDeselect
handleClick: @handleClick
noWrapOptions: noWrapOptions
disabled: option.disabled
className: option.className
}
pvrProps.scale = scale
pvrProps.close = close
pvrProps.element = div {
key: 'select-pvr'
className: 'select-pvr'
style: style
}, [
if @hasHeader
div {
key: 'header'
className: "header plain-pvr-content-item #{headerClass}"
}, headerTitle
div {
key: 'inner-rows'
}, optionEls
]
Pvr(pvrProps)
getInitialState: ->
{
selectedOption: @props.defaultSelected or null
}
handleClick: (option) ->
@setState
selectedOption: option
@props.onChange option
@props.close()
module.exports = SelectPvr