Merge pull request #3507 from matrix-org/bwindels/fixstucktooltip

Fix:  stuck tooltip with composer formatting bar
pull/21833/head
Bruno Windels 2019-10-02 14:52:17 +00:00 committed by GitHub
commit 173a8543a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 12 deletions

View File

@ -95,6 +95,8 @@ export default class InteractiveTooltip extends React.Component {
content: PropTypes.node.isRequired, content: PropTypes.node.isRequired,
// Function to call when visibility of the tooltip changes // Function to call when visibility of the tooltip changes
onVisibilityChange: PropTypes.func, onVisibilityChange: PropTypes.func,
// flag to forcefully hide this tooltip
forceHidden: PropTypes.bool,
}; };
constructor() { constructor() {
@ -269,8 +271,8 @@ export default class InteractiveTooltip extends React.Component {
renderTooltip() { renderTooltip() {
const { contentRect, visible } = this.state; const { contentRect, visible } = this.state;
if (!visible) { if (this.props.forceHidden === true || !visible) {
ReactDOM.unmountComponentAtNode(getOrCreateContainer()); ReactDOM.render(null, getOrCreateContainer());
return null; return null;
} }

View File

@ -18,7 +18,7 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import sdk from '../../../index'; import sdk from '../../../index';
import classNames from 'classnames';
export default class MessageComposerFormatBar extends React.PureComponent { export default class MessageComposerFormatBar extends React.PureComponent {
static propTypes = { static propTypes = {
@ -26,18 +26,26 @@ export default class MessageComposerFormatBar extends React.PureComponent {
shortcuts: PropTypes.object.isRequired, shortcuts: PropTypes.object.isRequired,
} }
constructor(props) {
super(props);
this.state = {visible: false};
}
render() { render() {
return (<div className="mx_MessageComposerFormatBar" ref={ref => this._formatBarRef = ref}> const classes = classNames("mx_MessageComposerFormatBar", {
<FormatButton shortcut={this.props.shortcuts.bold} label={_t("Bold")} onClick={() => this.props.onAction("bold")} icon="Bold" /> "mx_MessageComposerFormatBar_shown": this.state.visible,
<FormatButton shortcut={this.props.shortcuts.italics} label={_t("Italics")} onClick={() => this.props.onAction("italics")} icon="Italic" /> });
<FormatButton label={_t("Strikethrough")} onClick={() => this.props.onAction("strikethrough")} icon="Strikethrough" /> return (<div className={classes} ref={ref => this._formatBarRef = ref}>
<FormatButton label={_t("Code block")} onClick={() => this.props.onAction("code")} icon="Code" /> <FormatButton label={_t("Bold")} onClick={() => this.props.onAction("bold")} icon="Bold" shortcut={this.props.shortcuts.bold} visible={this.state.visible} />
<FormatButton shortcut={this.props.shortcuts.quote} label={_t("Quote")} onClick={() => this.props.onAction("quote")} icon="Quote" /> <FormatButton label={_t("Italics")} onClick={() => this.props.onAction("italics")} icon="Italic" shortcut={this.props.shortcuts.italics} visible={this.state.visible} />
<FormatButton label={_t("Strikethrough")} onClick={() => this.props.onAction("strikethrough")} icon="Strikethrough" visible={this.state.visible} />
<FormatButton label={_t("Code block")} onClick={() => this.props.onAction("code")} icon="Code" visible={this.state.visible} />
<FormatButton label={_t("Quote")} onClick={() => this.props.onAction("quote")} icon="Quote" shortcut={this.props.shortcuts.quote} visible={this.state.visible} />
</div>); </div>);
} }
showAt(selectionRect) { showAt(selectionRect) {
this._formatBarRef.classList.add("mx_MessageComposerFormatBar_shown"); this.setState({visible: true});
const parentRect = this._formatBarRef.parentElement.getBoundingClientRect(); const parentRect = this._formatBarRef.parentElement.getBoundingClientRect();
this._formatBarRef.style.left = `${selectionRect.left - parentRect.left}px`; this._formatBarRef.style.left = `${selectionRect.left - parentRect.left}px`;
// 12 is half the height of the bar (e.g. to center it) and 16 is an offset that felt ok. // 12 is half the height of the bar (e.g. to center it) and 16 is an offset that felt ok.
@ -45,7 +53,7 @@ export default class MessageComposerFormatBar extends React.PureComponent {
} }
hide() { hide() {
this._formatBarRef.classList.remove("mx_MessageComposerFormatBar_shown"); this.setState({visible: false});
} }
} }
@ -55,6 +63,7 @@ class FormatButton extends React.PureComponent {
onClick: PropTypes.func.isRequired, onClick: PropTypes.func.isRequired,
icon: PropTypes.string.isRequired, icon: PropTypes.string.isRequired,
shortcut: PropTypes.string, shortcut: PropTypes.string,
visible: PropTypes.bool,
} }
render() { render() {
@ -72,7 +81,7 @@ class FormatButton extends React.PureComponent {
); );
return ( return (
<InteractiveTooltip content={tooltipContent}> <InteractiveTooltip content={tooltipContent} forceHidden={!this.props.visible}>
<span aria-label={this.props.label} <span aria-label={this.props.label}
role="button" role="button"
onClick={this.props.onClick} onClick={this.props.onClick}