terriajs
Version:
Geospatial data visualization platform.
95 lines (82 loc) • 3.53 kB
JSX
;
// proptypes are in mixin
/* eslint react/prop-types:0*/
import React from 'react';
import createReactClass from 'create-react-class';
import classNames from 'classnames';
import Icon from "../../Icon.jsx";
import InnerPanel from './InnerPanel';
import BaseOuterPanel from './BaseOuterPanel';
import Styles from './panel.scss';
import defined from 'terriajs-cesium/Source/Core/defined';
const DropdownPanel = createReactClass({
displayName: 'DropdownPanel',
mixins: [BaseOuterPanel],
getInitialState() {
return {
localIsOpen: false,
caretOffset: undefined,
dropdownOffset: undefined
};
},
onInnerMounted(innerElement) {
if (innerElement) {
// how much further right the panel is from the button
const offset = this.buttonElement.offsetLeft - innerElement.offsetLeft;
// if the panel is left of the button leave its offset as is, otherwise move it right so it's level with the button.
const dropdownOffset = offset < innerElement.offsetLeft ? offset : innerElement.offsetLeft;
// offset the caret to line up with the middle of the button - note that the caret offset is relative to the panel, whereas
// the offsets for the button/panel are relative to their container.
const caretOffset = Math.max((this.buttonElement.clientWidth / 2 - 10) - (dropdownOffset - this.buttonElement.offsetLeft), 0);
this.setState({
caretOffset: caretOffset >= 0 && (caretOffset + 'px'),
dropdownOffset: dropdownOffset + 'px'
});
} else {
this.setState({
caretOffset: undefined,
dropdownOffset: undefined
});
}
},
/* eslint-disable-next-line camelcase */
UNSAFE_componentWillReceiveProps(nextProps) {
if (nextProps.forceClosed) {
this.onDismissed();
}
},
render() {
let iconGlyph;
if (defined(Icon.GLYPHS[this.props.theme.icon])) {
iconGlyph = Icon.GLYPHS[this.props.theme.icon];
} else {
iconGlyph = this.props.theme.icon;
}
return (
<div className={classNames(Styles.panel, this.props.theme.outer)}>
<button onClick={this.openPanel}
type='button'
className={classNames(Styles.button, this.props.theme.btn)}
title={this.props.btnTitle}
ref={element => this.buttonElement = element}>
<If condition={this.props.theme.icon}>
<Icon glyph={iconGlyph}/>
</If>
<span>{this.props.btnText}</span>
</button>
<If condition={this.isOpen()}>
<InnerPanel
onDismissed={this.onDismissed}
innerRef={this.onInnerMounted}
doNotCloseFlag={this.getDoNotCloseFlag()}
theme={this.props.theme}
caretOffset={this.state.caretOffset}
dropdownOffset={this.state.dropdownOffset}>
{this.props.children}
</InnerPanel>
</If>
</div>
);
},
});
export default DropdownPanel;