mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-01-26 10:01:57 +08:00
fix(popover): don't let popover overflow
Summary: The popover class now will adjust itself until it fits within the window frame. You don't see the intermediate state in the double render. Test Plan: edgehill --test Reviewers: bengotow Reviewed By: bengotow Differential Revision: https://phab.nylas.com/D1795
This commit is contained in:
parent
60ccd86de1
commit
9eb36f5813
5 changed files with 43 additions and 18 deletions
|
@ -28,12 +28,12 @@
|
|||
}
|
||||
|
||||
.message-toolbar-arrow.down {
|
||||
order:101;
|
||||
order:201;
|
||||
margin-right: 0;
|
||||
padding-top:6px;
|
||||
}
|
||||
.message-toolbar-arrow.up {
|
||||
order:102;
|
||||
order:202;
|
||||
padding-top:6px;
|
||||
// <1 because of hit region padding on the button
|
||||
margin-right: @spacing-standard * 0.75;
|
||||
|
|
|
@ -153,10 +153,10 @@ class Tooltip extends React.Component
|
|||
return left
|
||||
|
||||
_windowWidth: =>
|
||||
document.getElementsByTagName('body')[0].getBoundingClientRect().width
|
||||
document.body.offsetWidth
|
||||
|
||||
_windowHeight: =>
|
||||
document.getElementsByTagName('body')[0].getBoundingClientRect().height
|
||||
document.body.offsetHeight
|
||||
|
||||
_hideTooltip: =>
|
||||
@_lastTarget = null
|
||||
|
|
|
@ -213,10 +213,6 @@
|
|||
'tab': 'native!'
|
||||
'shift-tab': 'native!'
|
||||
|
||||
# For Popover Component
|
||||
'body .popover-container, body .popover-container input':
|
||||
'escape': 'popover:close'
|
||||
|
||||
# Tokenizing Text fields
|
||||
|
||||
# The default state. There's no input in the text field and there are no
|
||||
|
|
|
@ -68,20 +68,21 @@ class Popover extends React.Component
|
|||
constructor: (@props) ->
|
||||
@state =
|
||||
showing: false
|
||||
offset: 0
|
||||
dimensions: {}
|
||||
|
||||
componentDidMount: =>
|
||||
@subscriptions = new CompositeDisposable()
|
||||
@subscriptions.add atom.commands.add '.popover-container', {
|
||||
'popover:close': => @close()
|
||||
}
|
||||
window.addEventListener("resize", @_resetPositionState)
|
||||
@_resetPositionState()
|
||||
|
||||
componentWillUnmount: =>
|
||||
@subscriptions?.dispose()
|
||||
window.removeEventListener("resize", @_resetPositionState)
|
||||
|
||||
componentDidUpdate: ->
|
||||
if @_focusOnOpen
|
||||
@_focusImportantElement()
|
||||
@_focusOnOpen = false
|
||||
@_resetPositionState()
|
||||
|
||||
open: =>
|
||||
@_focusOnOpen = true
|
||||
|
@ -94,6 +95,26 @@ class Popover extends React.Component
|
|||
showing: false
|
||||
@props.onClosed?()
|
||||
|
||||
# We need to make sure that we're not rendered off the edge of the
|
||||
# browser window.
|
||||
_resetPositionState: ->
|
||||
return unless @state.showing
|
||||
rect = React.findDOMNode(@refs.popover).getBoundingClientRect()
|
||||
dimensions =
|
||||
left: rect.left
|
||||
right: rect.right
|
||||
docWidth: document.body.clientWidth
|
||||
|
||||
return if _.isEqual dimensions, @state.dimensions
|
||||
|
||||
padding = 11.25
|
||||
|
||||
origRight = dimensions.right - @state.offset
|
||||
origLeft = dimensions.left - @state.offset
|
||||
|
||||
offset = Math.min((dimensions.docWidth - padding - origRight), 0) - Math.min(origLeft - padding, 0)
|
||||
@setState {offset, dimensions}
|
||||
|
||||
_focusImportantElement: =>
|
||||
# Automatically focus the element inside us with the lowest tab index
|
||||
node = React.findDOMNode(@refs.popover)
|
||||
|
@ -113,10 +134,12 @@ class Popover extends React.Component
|
|||
wrappedButtonComponent = <div onClick={@_onClick}>{@props.buttonComponent}</div>
|
||||
|
||||
popoverComponent = []
|
||||
|
||||
if @state.showing
|
||||
popoverStyle =
|
||||
'position': 'absolute'
|
||||
'left': '50%'
|
||||
'left': "calc(50% + #{@state.offset})"
|
||||
'width': '250px'
|
||||
'zIndex': 40
|
||||
pointerStyle =
|
||||
'position': 'absolute'
|
||||
|
@ -147,7 +170,7 @@ class Popover extends React.Component
|
|||
popoverStyle = _.extend popoverStyle,
|
||||
'transform': 'translate(0, 2px)'
|
||||
'top': '100%'
|
||||
'left': 0
|
||||
'left': 0 + @state.offset
|
||||
pointerStyle = _.extend pointerStyle,
|
||||
'display': 'none'
|
||||
|
||||
|
@ -156,11 +179,18 @@ class Popover extends React.Component
|
|||
<div className="popover-pointer" style={pointerStyle}></div>
|
||||
</div>
|
||||
|
||||
<div className={"popover-container "+@props.className} onBlur={@_onBlur} ref="container" style={(@props.style ? {})}>
|
||||
<div className={"popover-container "+@props.className}
|
||||
onBlur={@_onBlur}
|
||||
onKeyDown={@_onKeyDown}
|
||||
style={(@props.style ? {})} ref="popoverContainer">
|
||||
{wrappedButtonComponent}
|
||||
{popoverComponent}
|
||||
</div>
|
||||
|
||||
_onKeyDown: (event) =>
|
||||
if event.key is "Escape"
|
||||
@close()
|
||||
|
||||
_onClick: =>
|
||||
if not @state.showing
|
||||
@open()
|
||||
|
@ -169,7 +199,7 @@ class Popover extends React.Component
|
|||
|
||||
_onBlur: (event) =>
|
||||
target = event.nativeEvent.relatedTarget
|
||||
if target? and React.findDOMNode(@refs.container).contains(target)
|
||||
if target? and React.findDOMNode(@refs.popoverContainer).contains(target)
|
||||
return
|
||||
@setState
|
||||
showing:false
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
.popover {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 250px;
|
||||
max-height:400px;
|
||||
background-color: @background-color;
|
||||
border-radius: @border-radius-base;
|
||||
|
|
Loading…
Reference in a new issue