UNPKG

terriajs

Version:

Geospatial data visualization platform.

93 lines (79 loc) 3.28 kB
import React from 'react'; import PropTypes from 'prop-types'; import createReactClass from 'create-react-class'; import classNames from 'classnames'; import defined from 'terriajs-cesium/Source/Core/defined'; import Styles from './panel.scss'; const InnerPanel = createReactClass({ propTypes: { /** * A property that will be looked for on window click events - if it's set, the click event will not cause the * panel to close. */ doNotCloseFlag: PropTypes.string, /** Will be called when the panel has finished hiding */ onDismissed: PropTypes.func, /** Theme to style components */ theme: PropTypes.object, /** How far the caret at the top of the panel should be from its left, as CSS (so #px or #% are both valid) */ caretOffset: PropTypes.string, /** Will be passed as "ref" to the outermost element */ innerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), /** How far the dropdown should be offset from the left of the container. */ dropdownOffset: PropTypes.string, children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.element), PropTypes.element]) }, getDefaultProps() { return { onDismissed: () => { } }; }, getInitialState() { return {}; }, componentDidMount() { window.addEventListener('click', this.close); setTimeout(() => this.setState({isOpenCss: true})); }, componentWillUnmount() { window.removeEventListener('click', this.close); }, close(e) { // Only close if this wasn't a click on an open/close button. if (!this.props.doNotCloseFlag || !e[this.props.doNotCloseFlag]) { window.removeEventListener('click', this.close); // If we're closing we want to immediately change the css class to cause it to animate shut, then when it's // finished actually stop it rendering with isOpen = false this.setState({ isOpenCss: false }); setTimeout(() => { this.props.onDismissed(); }, 200); // TODO: Determine when it stops animating instead of duplicating the 200ms timeout? } }, render() { return ( <div className={classNames( Styles.inner, this.props.theme.inner, {[Styles.isOpen]: this.state.isOpenCss} )} ref={this.props.innerRef} onClick={e => e.stopPropagation()} style={{ left: this.props.dropdownOffset, transformOrigin: this.props.caretOffset && `${this.props.caretOffset} top` }}> <If condition={defined(this.props.caretOffset)}> <span className={Styles.caret} style={{left: this.props.caretOffset}}/> </If> <div className={Styles.content}> {this.props.children} </div> </div> ); } }); export default InnerPanel;