terriajs
Version:
Geospatial data visualization platform.
89 lines • 4.4 kB
JavaScript
"use strict";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
/* eslint react/prop-types:0*/
import createReactClass from "create-react-class";
import classNames from "classnames";
import Icon from "../../../Styled/Icon";
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) {
const centerInnerDropdown = this.props.showDropdownInCenter;
if (centerInnerDropdown) {
this.setState({
caretOffset: "50%",
dropdownOffset: "50%"
});
}
else if (innerElement) {
const btnRef = this.props.btnRef;
const buttonElementOffsetLeft = btnRef?.current?.offsetLeft || this.buttonElement?.offsetLeft || 0;
const buttonElementClientWidth = btnRef?.current?.clientWidth || this.buttonElement?.clientWidth || 0;
// how much further right the panel is from the button
const offset = buttonElementOffsetLeft - 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(buttonElementClientWidth / 2 -
10 -
(dropdownOffset - buttonElementOffsetLeft), 0);
this.setState({
caretOffset: caretOffset >= 0 && caretOffset + "px",
dropdownOffset: dropdownOffset + "px"
});
}
else {
this.setState({
caretOffset: undefined,
dropdownOffset: undefined
});
}
},
UNSAFE_componentWillReceiveProps(nextProps) {
if (nextProps.forceClosed) {
this.onDismissed();
}
},
openWithUserClick(e) {
if (this.props.userOnClick) {
this.props.userOnClick();
}
this.openPanel(e);
},
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 (_jsxs("div", { className: classNames(Styles.panel, this.props.theme.outer), children: [_jsxs("button", { onClick: this.openWithUserClick, type: "button", className: classNames(Styles.button, this.props.theme.btn, {
[Styles.buttonForModalDropdown]: this.props.showDropdownAsModal
}), title: this.props.btnTitle, ref: this.props.btnRef || ((element) => (this.buttonElement = element)),
// eslint-disable-next-line react/no-unknown-property
isOpen: this.isOpen(), css: `
${(p) => p.isOpen &&
`&:not(.foo) {
background: ${p.theme.colorPrimary};
svg {
fill: ${p.theme.textLight};
}
}`}
`, children: [this.props.theme.icon && _jsx(Icon, { glyph: iconGlyph }), this.props.btnText && _jsx("span", { children: this.props.btnText })] }), this.isOpen() && (_jsx(InnerPanel, { showDropdownInCenter: this.props.showDropdownInCenter, showDropdownAsModal: this.props.showDropdownAsModal, modalWidth: this.props.modalWidth, onDismissed: this.onDismissed, innerRef: this.onInnerMounted, doNotCloseFlag: this.getDoNotCloseFlag(), theme: this.props.theme, caretOffset: this.state.caretOffset, dropdownOffset: this.state.dropdownOffset, disableCloseOnFocusLoss: this.props.disableCloseOnFocusLoss, children: this.props.children }))] }));
}
});
export default DropdownPanel;
//# sourceMappingURL=DropdownPanel.js.map