diff --git a/src/components/popover.cjsx b/src/components/popover.cjsx deleted file mode 100644 index 7fa3865d6..000000000 --- a/src/components/popover.cjsx +++ /dev/null @@ -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 Contents - -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
with an onClick handler. - - - `children` The React elements that should appear when the Popover is opened. - They're automatically wrapped in a `
`, 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 =
{@props.buttonComponent}
- - 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 = ( -
- {@props.children} -
- ) - -
- {wrappedButtonComponent} - {popoverComponent} -
-
-
- - _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 diff --git a/static/components/popover.less b/static/components/popover.less deleted file mode 100644 index 454ec5e06..000000000 --- a/static/components/popover.less +++ /dev/null @@ -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; - } - } -}