fix(dropdown): Open up or down depending on position

This commit is contained in:
Ben Gotow 2016-01-29 15:51:00 -08:00
parent 2027901deb
commit eec7c829ce
3 changed files with 53 additions and 22 deletions

View file

@ -87,7 +87,7 @@ class SendActionButton extends React.Component
_renderSendDropdown: ->
actionConfigs = @_orderedActionConfigs()
<ButtonDropdown
className={"btn-send dropdown-btn-emphasis dropdown-btn-text"}
className={"btn-send btn-emphasis btn-text"}
style={order: -100}
primaryItem={@_sendContent(actionConfigs[0].iconUrl)}
primaryTitle={actionConfigs[0].title}

View file

@ -1,5 +1,6 @@
RetinaImg = require './retina-img'
{Utils} = require 'nylas-exports'
classnames = require 'classnames'
React = require 'react'
class ButtonDropdown extends React.Component
@ -16,15 +17,17 @@ class ButtonDropdown extends React.Component
style: {}
constructor: (@props) ->
@state = showing: false
@state = open: false
render: =>
classnames = "button-dropdown #{@props.className ? ''}"
classnames += " open" if @state.showing
classnames += " bordered" if @props.bordered isnt false
classes = classnames
'button-dropdown': true
'open open-up': @state.open is 'up'
'open open-down': @state.open is 'down'
'bordered': @props.bordered isnt false
if @props.primaryClick
<div ref="button" onBlur={@_onBlur} tabIndex={999} className={classnames} style={@props.style}>
<div ref="button" onBlur={@_onBlur} tabIndex={999} className={"#{classes} #{@props.className ? ''}"} style={@props.style}>
<div className="primary-item"
title={@props.primaryTitle ? ""}
onClick={@props.primaryClick}>
@ -33,34 +36,42 @@ class ButtonDropdown extends React.Component
<div className="secondary-picker" onClick={@toggleDropdown}>
<RetinaImg name={"icon-thread-disclosure.png"} mode={RetinaImg.Mode.ContentIsMask}/>
</div>
<div className="secondary-items" onMouseDown={@_onMenuClick}>
<div ref="secondaryItems" className="secondary-items" onMouseDown={@_onMenuClick}>
{@props.menu}
</div>
</div>
else
<div ref="button" onBlur={@_onBlur} tabIndex={999} className={classnames} style={@props.style}>
<div ref="button" onBlur={@_onBlur} tabIndex={999} className={"#{classes} #{@props.className ? ''}"} style={@props.style}>
<div className="only-item"
title={@props.primaryTitle ? ""}
onClick={@toggleDropdown}>
{@props.primaryItem}
<RetinaImg name={"icon-thread-disclosure.png"} style={marginLeft:12} mode={RetinaImg.Mode.ContentIsMask}/>
</div>
<div className="secondary-items left" onMouseDown={@_onMenuClick}>
<div ref="secondaryItems" className="secondary-items left" onMouseDown={@_onMenuClick}>
{@props.menu}
</div>
</div>
toggleDropdown: =>
@setState(showing: !@state.showing)
if @state.open isnt false
@setState(open: false)
else
buttonBottom = React.findDOMNode(@).getBoundingClientRect().bottom
openHeight = React.findDOMNode(@refs.secondaryItems).getBoundingClientRect().height
if buttonBottom + openHeight > window.innerHeight
@setState(open: 'up')
else
@setState(open: 'down')
_onMenuClick: (event) =>
if @props.closeOnMenuClick
@setState showing: false
@setState open: false
_onBlur: (event) =>
target = event.nativeEvent.relatedTarget
if target? and React.findDOMNode(@refs.button).contains(target)
return
@setState(showing: false)
@setState(open: false)
module.exports = ButtonDropdown

View file

@ -5,14 +5,33 @@
display: inline-block;
&.open {
.secondary-items {
visibility: inherit;
}
}
&.open.open-up {
.secondary-items {
border-radius: 4px 4px 0 4px;
box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.20);
top: -100%;
transform:translate(0, -2px);
}
.secondary-picker {
border-top-right-radius: 0;
}
}
&.open.open-down {
.secondary-items {
border-radius: 4px 0 4px 4px;
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.20);
}
.secondary-picker {
border-bottom-right-radius: 0;
}
.secondary-items {
display:block;
}
}
&.bordered,
&:hover {
.primary-item,
@ -25,15 +44,18 @@
}
}
&.dropdown-btn-emphasis {
&.btn-emphasis {
.primary-item,
.secondary-picker,
.only-item {
.btn.btn-emphasis;
}
.primary-item {
border-right:0;
}
}
&.dropdown-btn-text {
&.btn-text {
.primary-item,
.secondary-picker,
.only-item {
@ -97,15 +119,13 @@
white-space:nowrap;
}
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 4px 0 4px 4px;
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.20);
z-index: 2;
background-color: @background-primary;
line-height: 14px;
position: absolute;
right: -1px; // -1, because of the border above
white-space:nowrap;
display:none;
visibility:hidden;
.menu {
.footer-container,
@ -168,7 +188,7 @@ body.platform-win32 {
.secondary-items {
border-radius: 0;
}
&.dropdown-btn-emphasis {
&.btn-emphasis {
.primary-item,
.secondary-picker,
.only-item {
@ -184,7 +204,7 @@ body.platform-win32 {
}
}
}
&.dropdown-btn-text {
&.btn-text {
.primary-item,
.secondary-picker,
.only-item {