Adapt <Tooltip> to use an Alignment enum instead
This commit is contained in:
parent
f25a4214e3
commit
22219e0e80
3 changed files with 46 additions and 10 deletions
|
@ -262,7 +262,7 @@ export default class Field extends React.PureComponent<PropShapes, IState> {
|
||||||
tooltipClassName={classNames("mx_Field_tooltip", tooltipClassName)}
|
tooltipClassName={classNames("mx_Field_tooltip", tooltipClassName)}
|
||||||
visible={(this.state.focused && this.props.forceTooltipVisible) || this.state.feedbackVisible}
|
visible={(this.state.focused && this.props.forceTooltipVisible) || this.state.feedbackVisible}
|
||||||
label={tooltipContent || this.state.feedback}
|
label={tooltipContent || this.state.feedback}
|
||||||
forceOnRight
|
alignment={Tooltip.Alignment.Right}
|
||||||
/>;
|
/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,8 @@ limitations under the License.
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import Tooltip from './Tooltip';
|
import Tooltip, {Alignment} from './Tooltip';
|
||||||
import { _t } from "../../../languageHandler";
|
import {_t} from "../../../languageHandler";
|
||||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||||
|
|
||||||
interface ITooltipProps {
|
interface ITooltipProps {
|
||||||
|
@ -61,7 +61,7 @@ export default class InfoTooltip extends React.PureComponent<ITooltipProps, ISta
|
||||||
className="mx_InfoTooltip_container"
|
className="mx_InfoTooltip_container"
|
||||||
tooltipClassName={classNames("mx_InfoTooltip_tooltip", tooltipClassName)}
|
tooltipClassName={classNames("mx_InfoTooltip_tooltip", tooltipClassName)}
|
||||||
label={tooltip || title}
|
label={tooltip || title}
|
||||||
forceOnRight={true}
|
alignment={Alignment.Right}
|
||||||
/> : <div />;
|
/> : <div />;
|
||||||
return (
|
return (
|
||||||
<div onMouseOver={this.onMouseOver} onMouseLeave={this.onMouseLeave} className="mx_InfoTooltip">
|
<div onMouseOver={this.onMouseOver} onMouseLeave={this.onMouseLeave} className="mx_InfoTooltip">
|
||||||
|
|
|
@ -25,6 +25,14 @@ import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||||
|
|
||||||
const MIN_TOOLTIP_HEIGHT = 25;
|
const MIN_TOOLTIP_HEIGHT = 25;
|
||||||
|
|
||||||
|
export enum Alignment {
|
||||||
|
Natural, // Pick left or right
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
Top, // Centered
|
||||||
|
Bottom, // Centered
|
||||||
|
}
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
// Class applied to the element used to position the tooltip
|
// Class applied to the element used to position the tooltip
|
||||||
className?: string;
|
className?: string;
|
||||||
|
@ -36,7 +44,7 @@ interface IProps {
|
||||||
visible?: boolean;
|
visible?: boolean;
|
||||||
// the react element to put into the tooltip
|
// the react element to put into the tooltip
|
||||||
label: React.ReactNode;
|
label: React.ReactNode;
|
||||||
forceOnRight?: boolean;
|
alignment?: Alignment; // defaults to Natural
|
||||||
yOffset?: number;
|
yOffset?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,10 +54,14 @@ export default class Tooltip extends React.Component<IProps> {
|
||||||
private tooltip: void | Element | Component<Element, any, any>;
|
private tooltip: void | Element | Component<Element, any, any>;
|
||||||
private parent: Element;
|
private parent: Element;
|
||||||
|
|
||||||
|
// XXX: This is because some components (Field) are unable to `import` the Tooltip class,
|
||||||
|
// so we expose the Alignment options off of us statically.
|
||||||
|
public static readonly Alignment = Alignment;
|
||||||
|
|
||||||
public static readonly defaultProps = {
|
public static readonly defaultProps = {
|
||||||
visible: true,
|
visible: true,
|
||||||
yOffset: 0,
|
yOffset: 0,
|
||||||
|
alignment: Alignment.Natural,
|
||||||
};
|
};
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -86,11 +98,35 @@ export default class Tooltip extends React.Component<IProps> {
|
||||||
offset = Math.floor(parentBox.height - MIN_TOOLTIP_HEIGHT);
|
offset = Math.floor(parentBox.height - MIN_TOOLTIP_HEIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
style.top = (parentBox.top - 2 + this.props.yOffset) + window.pageYOffset + offset;
|
const baseTop = (parentBox.top - 2 + this.props.yOffset) + window.pageYOffset;
|
||||||
if (!this.props.forceOnRight && parentBox.right > window.innerWidth / 2) {
|
const top = baseTop + offset;
|
||||||
style.right = window.innerWidth - parentBox.right - window.pageXOffset - 16;
|
const right = window.innerWidth - parentBox.right - window.pageXOffset - 16;
|
||||||
} else {
|
const left = parentBox.right + window.pageXOffset + 6;
|
||||||
style.left = parentBox.right + window.pageXOffset + 6;
|
const horizontalCenter = parentBox.right - window.pageXOffset - (parentBox.width / 2);
|
||||||
|
switch(this.props.alignment) {
|
||||||
|
case Alignment.Natural:
|
||||||
|
if (parentBox.right > window.innerWidth / 2) {
|
||||||
|
style.right = right;
|
||||||
|
style.top = top;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// fall through to Right
|
||||||
|
case Alignment.Right:
|
||||||
|
style.left = left;
|
||||||
|
style.top = top;
|
||||||
|
break;
|
||||||
|
case Alignment.Left:
|
||||||
|
style.right = right;
|
||||||
|
style.top = top;
|
||||||
|
break;
|
||||||
|
case Alignment.Top:
|
||||||
|
style.top = baseTop - 16;
|
||||||
|
style.left = horizontalCenter;
|
||||||
|
break;
|
||||||
|
case Alignment.Bottom:
|
||||||
|
style.top = baseTop + parentBox.height;
|
||||||
|
style.left = horizontalCenter;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return style;
|
return style;
|
||||||
|
|
Loading…
Reference in a new issue