Animate tooltips when hiding as well as showing

This uses the same animation style as on show, but twice as fast.
This commit is contained in:
J. Ryan Stinnett 2019-04-25 11:10:35 +01:00
parent 0b42ded007
commit 26f732723e
3 changed files with 40 additions and 6 deletions

View file

@ -50,7 +50,6 @@ limitations under the License.
.mx_Tooltip { .mx_Tooltip {
display: none; display: none;
animation: mx_fadein 0.2s;
position: fixed; position: fixed;
border: 1px solid $menu-border-color; border: 1px solid $menu-border-color;
border-radius: 4px; border-radius: 4px;
@ -66,4 +65,12 @@ limitations under the License.
max-width: 200px; max-width: 200px;
word-break: break-word; word-break: break-word;
margin-right: 50px; margin-right: 50px;
&.mx_Tooltip_visible {
animation: mx_fadein 0.2s forwards;
}
&.mx_Tooltip_invisible {
animation: mx_fadeout 0.1s forwards;
}
} }

View file

@ -99,10 +99,23 @@ export default class Field extends React.PureComponent {
focused, focused,
allowEmpty, allowEmpty,
}); });
if (feedback) {
this.setState({ this.setState({
valid, valid,
feedback, feedback,
feedbackVisible: true,
}); });
} else {
// When we receive null `feedback`, we want to hide the tooltip.
// We leave the previous `feedback` content in state without updating it,
// so that we can hide the tooltip containing the most recent feedback
// via CSS animation.
this.setState({
valid,
feedbackVisible: false,
});
}
} }
validateOnChange = throttle(() => { validateOnChange = throttle(() => {
@ -147,6 +160,7 @@ export default class Field extends React.PureComponent {
if (this.state.feedback) { if (this.state.feedback) {
tooltip = <Tooltip tooltip = <Tooltip
tooltipClassName="mx_Field_tooltip" tooltipClassName="mx_Field_tooltip"
visible={this.state.feedbackVisible}
label={this.state.feedback} label={this.state.feedback}
/>; />;
} }

View file

@ -31,10 +31,20 @@ module.exports = React.createClass({
className: React.PropTypes.string, className: React.PropTypes.string,
// Class applied to the tooltip itself // Class applied to the tooltip itself
tooltipClassName: React.PropTypes.string, tooltipClassName: React.PropTypes.string,
// Whether the tooltip is visible or hidden.
// The hidden state allows animating the tooltip away via CSS.
// Defaults to visible if unset.
visible: React.PropTypes.bool,
// the react element to put into the tooltip // the react element to put into the tooltip
label: React.PropTypes.node, label: React.PropTypes.node,
}, },
getDefaultProps() {
return {
visible: true,
};
},
// Create a wrapper for the tooltip outside the parent and attach it to the body element // Create a wrapper for the tooltip outside the parent and attach it to the body element
componentDidMount: function() { componentDidMount: function() {
this.tooltipContainer = document.createElement("div"); this.tooltipContainer = document.createElement("div");
@ -85,7 +95,10 @@ module.exports = React.createClass({
style = this._updatePosition(style); style = this._updatePosition(style);
style.display = "block"; style.display = "block";
const tooltipClasses = classNames("mx_Tooltip", this.props.tooltipClassName); const tooltipClasses = classNames("mx_Tooltip", this.props.tooltipClassName, {
"mx_Tooltip_visible": this.props.visible,
"mx_Tooltip_invisible": !this.props.visible,
});
const tooltip = ( const tooltip = (
<div className={tooltipClasses} style={style}> <div className={tooltipClasses} style={style}>