fix(popover): 🔪 deprecated popover

This commit is contained in:
Juan Tejada 2016-10-24 16:33:17 -07:00
parent a95c17bce3
commit 5e7c1ad518
2 changed files with 0 additions and 304 deletions

View file

@ -1,222 +0,0 @@
React = require 'react'
ReactDOM = require 'react-dom'
_ = require 'underscore'
{CompositeDisposable} = require 'event-kit'
###
Public: The Popover component makes it easy to display a sheet or popup menu when the
user clicks the React element provided as `buttonComponent`. In N1, the Popover
component is used to create rich dropdown menus, detail popups, etc. with consistent
look and feel and behavior.
The Popover component handles:
- Rendering it's children when you click `buttonComponent`, and dismissing it's
children when you click outside the popover or press the Escape key.
- Automatically focusing the item with the lowest tabIndex inside the popover
## Input Focus
If your Popover contains an input, like a search bar, give it a tabIndex and
Popover will automatically focus it when the popover is opened.
## Advanced Use
If you don't want to use the Popover in conjunction with a triggering button,
you can manually call `open()` and `close()` to display it. A typical scenario
looks like this:
```coffeescript
render: =>
<Popover ref="myPopover"> Popover Contents </Popover>
showMyPopover: =>
@refs.myPopover.open()
```
Section: Component Kit
###
class Popover extends React.Component
###
Public: React `props` supported by Popover:
- `buttonComponent` The React element that will be rendered in place of the
Popover and trigger it to appear. This is typically a button or call-to-action for
opening the popover. Popover wraps this item in a <div> with an onClick handler.
- `children` The React elements that should appear when the Popover is opened.
They're automatically wrapped in a `<div class="popover">`, which applies standard
shadowing and styles.
- `direction` Defaults to 'up'. You can also pass 'down' to make the Popover float beneath
the button component.
- `pointerStyle` Additional styles to apply to the pointer
- `popoverStyle` Additional styles to apply to the popover
Events
- `onOpened` A {Function} that will be called when the popover is opened.
###
@propTypes =
buttonComponent: React.PropTypes.element
direction: React.PropTypes.string
popoverStyle: React.PropTypes.object
pointerStyle: React.PropTypes.object
@defaultProps =
direction: 'up'
constructor: (@props) ->
@state =
showing: false
offset: 0
dimensions: {}
componentDidMount: =>
window.addEventListener("resize", @_resetPositionState)
@_resetPositionState()
componentWillUnmount: =>
window.removeEventListener("resize", @_resetPositionState)
componentDidUpdate: =>
if @_focusOnOpen
@_focusImportantElement()
@_focusOnOpen = false
@_resetPositionState()
open: =>
@_focusOnOpen = true
@setState
showing: true
@props.onOpened?()
close: =>
@setState
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 = ReactDOM.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 = ReactDOM.findDOMNode(@refs.popover)
# _.sortBy ranks in ascending numerical order.
matches = _.sortBy node.querySelectorAll("[tabIndex], input"), (node) =>
if node.tabIndex > 0
return node.tabIndex
else if node.nodeName is "INPUT"
return 1000000
else return 1000001
matches[0]?.focus()
render: =>
wrappedButtonComponent = []
if @props.buttonComponent
wrappedButtonComponent = <div onClick={@_onClick}>{@props.buttonComponent}</div>
popoverComponent = []
if @state.showing
popoverStyle =
'position': 'absolute'
'left': "calc(50% + #{@state.offset}px)"
'zIndex': 40
pointerStyle =
'position': 'absolute'
'marginLeft': '50%'
'zoom': 0.5
'width': 45
'height': 20
'zIndex': 40
if @props.direction is 'up'
popoverStyle = _.extend popoverStyle,
'transform': 'translate(-50%,-100%)'
'top': -10,
pointerStyle = _.extend pointerStyle,
'transform': 'translateX(-50%)'
'bottom': 48
else if @props.direction is 'down'
popoverStyle = _.extend popoverStyle,
'transform': 'translate(-50%, 15px)'
'top': '100%'
pointerStyle = _.extend pointerStyle,
'transform': 'rotateX(180deg)'
'top': 71
'left':-12
if @props.direction is "down-align-left"
popoverStyle = _.extend popoverStyle,
'transform': 'translate(0, 2px)'
'top': '100%'
'left': 0 + @state.offset
pointerStyle = _.extend pointerStyle,
'transform': 'rotateX(180deg)'
'top': 71
'display': 'none'
popoverStyle = _.extend({}, popoverStyle, @props.popoverStyle) if @props.popoverStyle
pointerStyle = _.extend({}, pointerStyle, @props.pointerStyle) if @props.pointerStyle
popoverComponent = (
<div ref="popover" className={"popover popover-"+@props.direction} style={popoverStyle}>
{@props.children}
</div>
)
<div className={"popover-container "+@props.className}
onBlur={@_onBlur}
onKeyDown={@_onKeyDown}
style={(@props.style ? {})} ref="popoverContainer">
{wrappedButtonComponent}
{popoverComponent}
<div className="popover-pointer" style={pointerStyle} />
<div className="popover-pointer shadow" style={pointerStyle} />
</div>
_onKeyDown: (event) =>
if event.key is "Escape"
@close()
_onClick: (e) =>
e.stopPropagation()
if not @state.showing
@open()
else
@close()
_onBlur: (event) =>
target = event.nativeEvent.relatedTarget
if target? and ReactDOM.findDOMNode(@refs.popoverContainer).contains(target)
return
@setState
showing:false
module.exports = Popover

View file

@ -1,82 +0,0 @@
@import "ui-variables";
@header-color: #afafaf;
.popover-container {
display:inline-block;
position:relative;
white-space: nowrap; // prevent dropdown arrow from wrapping when space constrained
}
.popover {
background-color: @background-secondary;
border-radius: @border-radius-base;
box-shadow: 0 0.5px 0 rgba(0, 0, 0, 0.15), 0 -0.5px 0 rgba(0, 0, 0, 0.15), 0.5px 0 0 rgba(0, 0, 0, 0.15), -0.5px 0 0 rgba(0, 0, 0, 0.15), 0 4px 7px rgba(0,0,0,0.15);
min-width: 200px;
.menu {
z-index:1;
position: relative;
.content-container {
background: none;
}
.header-container {
border-top-left-radius: @border-radius-base;
border-top-right-radius: @border-radius-base;
background: none;
color: @header-color;
font-weight: bold;
border-bottom: none;
overflow: hidden;
padding: @padding-base-vertical * 1.5 @padding-base-horizontal;
}
.footer-container {
border-bottom-left-radius: @border-radius-base;
border-bottom-right-radius: @border-radius-base;
background: none;
.item:last-child:hover {
border-bottom-left-radius: @border-radius-base;
border-bottom-right-radius: @border-radius-base;
}
}
}
input[type=text] {
border: 1px solid darken(@background-secondary, 10%);
border-radius: 3px;
background-color: @background-primary;
box-shadow: inset 0 1px 0 rgba(0,0,0,0.05), 0 1px 0 rgba(0,0,0,0.05);
color: @text-color;
&.search {
padding-left: 0;
background-repeat: no-repeat;
background-image: url("../static/images/search/searchloupe@2x.png");
background-size: 15px 15px;
background-position: 7px 4px;
text-indent: 31px;
}
}
}
.popover-pointer {
-webkit-mask-image: url('images/tooltip/tooltip-bg-pointer@2x.png');
background-color: @background-secondary;
}
.popover-pointer.shadow {
-webkit-mask-image: url('images/tooltip/tooltip-bg-pointer-shadow@2x.png');
background-color: fade(@black, 22%);
}
body.platform-win32 {
.popover {
border-radius: 0;
}
.menu {
.header-container,
.footer-container {
border-radius: 0;
}
}
}