UNPKG

ldx-widgets

Version:

widgets

181 lines (140 loc) 4.49 kB
React = require 'react' _ = require 'lodash' {Flux} = require 'delorean' PvrInfoItem = require './pvr_info_item' animationMixin = require '../mixins/animation_mixin' {div} = React.DOM ### 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 ### PvrInfoList = React.createClass displayName: 'PvrInfoList' mixins: [animationMixin, Flux.mixins.storeListener] watchStores: ['popoverModal'] enterStateStart: scale: .9 enterStateEnd: scale: 1 enterEasing: 'easeOutElastic' enterDuration: 600 getDefaultProps: -> { items: [] height: 'auto' width: 250 styleMixin: {} itemHeight: 30 position: 'bottom' offsetTop: 0 offsetLeft: 0 showNib: yes } componentWillMount: -> window.addEventListener("resize", @updateDimensions) componentWillUnmount: -> window.removeEventListener("resize", @updateDimensions) updateDimensions: -> @forceUpdate() render: -> {width, height, styleMixin, items, itemHeight, position, element, offsetTop, offsetLeft, headerTitle, showNib} = @props {scale} = @state @hasHeader = headerTitle? if items? height = items.length * itemHeight + (items.length - 1) if height is 'auto' if @hasHeader height += 34 elPos = if element then element.getBoundingClientRect() else {} # Set the styles style = height: height + 20 width: width top: (elPos.top or 0) + offsetTop left: (elPos.left or 0) + offsetLeft transform: "scale(#{scale})" WebkitTransform: "scale(#{scale})" msTransform: "scale(#{scale})" # Handle the auto-positioning based on the element's screen position if element left = (-> if width < element.clientWidth then (element.clientWidth - width) / 2 else if width > element.clientWidth then -((width / 2) - (element.clientWidth / 2)) else 0 )() # Adjust the position if it is off-screen 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 # Adjust the position of the nib to account for the offscreen adjustment nibLeft = (element.clientWidth / 2) + Math.abs(leftAdjust) # Change the position of the popover switch position when 'bottom' style.top += element.clientHeight + 5 style.left += left _.assign style, styleMixin itemRows = [] if items? for item in items itemRows.push PvrInfoItem { hasSubLabel: item.subLabel? item: item itemHeight: itemHeight key: item.key } if itemRows.length is 0 itemRows = div {className: 'no-items'}, t 'No information to display' nibClass = "nib" if @hasHeader nibClass += " headerNib" div { className: "plain-pvr #{position}" style: style }, [ div { key: 'nib' className: nibClass style: left: nibLeft or '50%' } if showNib div { key: 'inner' className: 'inner' }, [ if @hasHeader div { key: 'header' className: 'header plain-pvr-content-item' }, headerTitle div { key: 'inner-rows' className: 'inner-rows' }, itemRows ] ] module.exports = PvrInfoList