Display a tooltip when you hover over a location (#7472)

This commit is contained in:
Andy Balaam 2022-01-07 15:11:30 +00:00 committed by GitHub
parent 707f8cd878
commit 309f7bb235
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 6 deletions

View file

@ -32,6 +32,7 @@ export enum Alignment {
Right, Right,
Top, // Centered Top, // Centered
Bottom, // Centered Bottom, // Centered
InnerBottom, // Inside the target, at the bottom
} }
export interface ITooltipProps { export interface ITooltipProps {
@ -50,6 +51,8 @@ export interface ITooltipProps {
// id describing tooltip // id describing tooltip
// used to associate tooltip with target for a11y // used to associate tooltip with target for a11y
id?: string; id?: string;
// If the parent is over this width, act as if it is only this wide
maxParentWidth?: number;
} }
@replaceableComponent("views.elements.Tooltip") @replaceableComponent("views.elements.Tooltip")
@ -107,11 +110,18 @@ export default class Tooltip extends React.Component<ITooltipProps> {
offset = Math.floor(parentBox.height - MIN_TOOLTIP_HEIGHT); offset = Math.floor(parentBox.height - MIN_TOOLTIP_HEIGHT);
} }
const width = UIStore.instance.windowWidth; const width = UIStore.instance.windowWidth;
const parentWidth = (
this.props.maxParentWidth
? Math.min(parentBox.width, this.props.maxParentWidth)
: parentBox.width
);
const baseTop = (parentBox.top - 2 + this.props.yOffset) + window.pageYOffset; const baseTop = (parentBox.top - 2 + this.props.yOffset) + window.pageYOffset;
const top = baseTop + offset; const top = baseTop + offset;
const right = width - parentBox.right - window.pageXOffset - 16; const right = width - parentBox.right - window.pageXOffset - 16;
const left = parentBox.right + window.pageXOffset + 6; const left = parentBox.right + window.pageXOffset + 6;
const horizontalCenter = parentBox.right - window.pageXOffset - (parentBox.width / 2); const horizontalCenter = (
parentBox.left - window.pageXOffset + (parentWidth / 2)
);
switch (this.props.alignment) { switch (this.props.alignment) {
case Alignment.Natural: case Alignment.Natural:
if (parentBox.right > width / 2) { if (parentBox.right > width / 2) {
@ -136,6 +146,10 @@ export default class Tooltip extends React.Component<ITooltipProps> {
style.top = baseTop + parentBox.height; style.top = baseTop + parentBox.height;
style.left = horizontalCenter; style.left = horizontalCenter;
break; break;
case Alignment.InnerBottom:
style.top = baseTop + parentBox.height - 50;
style.left = horizontalCenter;
style.transform = "translate(-50%)";
} }
return style; return style;

View file

@ -36,6 +36,7 @@ const TooltipTarget: React.FC<IProps> = ({
alignment, alignment,
yOffset, yOffset,
tooltipClassName, tooltipClassName,
maxParentWidth,
...rest ...rest
}) => { }) => {
const [isVisible, setIsVisible] = useState(false); const [isVisible, setIsVisible] = useState(false);
@ -63,6 +64,7 @@ const TooltipTarget: React.FC<IProps> = ({
yOffset={yOffset} yOffset={yOffset}
alignment={alignment} alignment={alignment}
visible={isVisible} visible={isVisible}
maxParentWidth={maxParentWidth}
/> />
</div> </div>
); );

View file

@ -27,6 +27,8 @@ import { _t } from '../../../languageHandler';
import MemberAvatar from '../avatars/MemberAvatar'; import MemberAvatar from '../avatars/MemberAvatar';
import Modal from '../../../Modal'; import Modal from '../../../Modal';
import LocationViewDialog from '../location/LocationViewDialog'; import LocationViewDialog from '../location/LocationViewDialog';
import TooltipTarget from '../elements/TooltipTarget';
import { Alignment } from '../elements/Tooltip';
interface IState { interface IState {
error: Error; error: Error;
@ -93,6 +95,7 @@ export default class MLocationBody extends React.Component<IBodyProps, IState> {
bodyId={this.getBodyId()} bodyId={this.getBodyId()}
markerId={this.getMarkerId()} markerId={this.getMarkerId()}
error={this.state.error} error={this.state.error}
tooltip={_t("Expand map")}
onClick={this.onClick} onClick={this.onClick}
/>; />;
} }
@ -103,10 +106,17 @@ interface ILocationBodyContentProps {
bodyId: string; bodyId: string;
markerId: string; markerId: string;
error: Error; error: Error;
tooltip?: string;
onClick?: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void; onClick?: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
} }
export function LocationBodyContent(props: ILocationBodyContentProps) { export function LocationBodyContent(props: ILocationBodyContentProps) {
const mapDiv = <div
id={props.bodyId}
onClick={props.onClick}
className="mx_MLocationBody_map"
/>;
return <div className="mx_MLocationBody"> return <div className="mx_MLocationBody">
{ {
props.error props.error
@ -115,11 +125,17 @@ export function LocationBodyContent(props: ILocationBodyContentProps) {
</div> </div>
: null : null
} }
<div {
id={props.bodyId} props.tooltip
onClick={props.onClick} ? <TooltipTarget
className="mx_MLocationBody_map" label={props.tooltip}
/> alignment={Alignment.InnerBottom}
maxParentWidth={450}
>
{ mapDiv }
</TooltipTarget>
: mapDiv
}
<div className="mx_MLocationBody_marker" id={props.markerId}> <div className="mx_MLocationBody_marker" id={props.markerId}>
<div className="mx_MLocationBody_markerBorder"> <div className="mx_MLocationBody_markerBorder">
<MemberAvatar <MemberAvatar

View file

@ -2091,6 +2091,7 @@
"Declining …": "Declining …", "Declining …": "Declining …",
"%(name)s wants to verify": "%(name)s wants to verify", "%(name)s wants to verify": "%(name)s wants to verify",
"You sent a verification request": "You sent a verification request", "You sent a verification request": "You sent a verification request",
"Expand map": "Expand map",
"Failed to load map": "Failed to load map", "Failed to load map": "Failed to load map",
"Vote not registered": "Vote not registered", "Vote not registered": "Vote not registered",
"Sorry, your vote was not registered. Please try again.": "Sorry, your vote was not registered. Please try again.", "Sorry, your vote was not registered. Please try again.": "Sorry, your vote was not registered. Please try again.",