Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Use Compound tooltips instead of homegrown in TextWithTooltip & InfoTooltip #12052

Merged
merged 15 commits into from
Dec 19, 2023
Merged
4 changes: 4 additions & 0 deletions res/css/_common.pcss
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ limitations under the License.
--dialog-zIndex-standard: calc(var(--dialog-zIndex-standard-background) + 1); /* 4012 */
}

#matrixchat {
contain: strict;
}

/**
* We need to increase the specificity of the selector to override the
* custom property set by the design tokens package
Expand Down
16 changes: 8 additions & 8 deletions src/components/views/avatars/DecoratedRoomAvatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import React from "react";
import classNames from "classnames";
import { Room, RoomEvent, MatrixEvent, User, UserEvent, EventType, JoinRule } from "matrix-js-sdk/src/matrix";
import { UnstableValue } from "matrix-js-sdk/src/NamespacedValue";
import { Tooltip } from "@vector-im/compound-web";

import RoomAvatar from "./RoomAvatar";
import NotificationBadge from "../rooms/NotificationBadge";
Expand All @@ -26,10 +27,8 @@ import { NotificationState } from "../../../stores/notifications/NotificationSta
import { isPresenceEnabled } from "../../../utils/presence";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
import { _t } from "../../../languageHandler";
import TextWithTooltip from "../elements/TextWithTooltip";
import DMRoomMap from "../../../utils/DMRoomMap";
import { IOOBData } from "../../../stores/ThreepidInviteStore";
import TooltipTarget from "../elements/TooltipTarget";

interface IProps {
room: Room;
Expand All @@ -38,7 +37,9 @@ interface IProps {
forceCount?: boolean;
oobData?: IOOBData;
viewAvatarOnClick?: boolean;
tooltipProps?: Omit<React.ComponentProps<typeof TooltipTarget>, "label" | "tooltipClassName" | "className">;
tooltipProps?: {
tabIndex?: number;
};
}

interface IState {
Expand Down Expand Up @@ -191,10 +192,9 @@ export default class DecoratedRoomAvatar extends React.PureComponent<IProps, ISt
let icon: JSX.Element | undefined;
if (this.state.icon !== Icon.None) {
icon = (
<TextWithTooltip
tooltip={tooltipText(this.state.icon)}
tooltipProps={this.props.tooltipProps}
class={`mx_DecoratedRoomAvatar_icon mx_DecoratedRoomAvatar_icon_${this.state.icon.toLowerCase()}`}
<div
tabIndex={this.props.tooltipProps?.tabIndex ?? 0}
className={`mx_DecoratedRoomAvatar_icon mx_DecoratedRoomAvatar_icon_${this.state.icon.toLowerCase()}`}
/>
);
}
Expand All @@ -211,7 +211,7 @@ export default class DecoratedRoomAvatar extends React.PureComponent<IProps, ISt
oobData={this.props.oobData}
viewAvatarOnClick={this.props.viewAvatarOnClick}
/>
{icon}
{icon && <Tooltip label={tooltipText(this.state.icon)!}>{icon}</Tooltip>}
{badge}
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/views/dialogs/ServerPickerDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ export default class ServerPickerDialog extends React.PureComponent<IProps, ISta
let defaultServerName: React.ReactNode = this.defaultServer.hsName;
if (this.defaultServer.hsNameIsDifferent) {
defaultServerName = (
<TextWithTooltip class="mx_Login_underlinedServerName" tooltip={this.defaultServer.hsUrl}>
<TextWithTooltip className="mx_Login_underlinedServerName" tooltip={this.defaultServer.hsUrl}>
{this.defaultServer.hsName}
</TextWithTooltip>
);
Expand Down
13 changes: 7 additions & 6 deletions src/components/views/elements/AppPermission.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ import MemberAvatar from "../avatars/MemberAvatar";
import BaseAvatar from "../avatars/BaseAvatar";
import Heading from "../typography/Heading";
import AccessibleButton from "./AccessibleButton";
import TextWithTooltip from "./TextWithTooltip";
import { parseUrl } from "../../../utils/UrlUtils";
import { Icon as HelpIcon } from "../../../../res/img/feather-customised/help-circle.svg";
import TooltipTarget from "./TooltipTarget";

interface IProps {
url: string;
Expand Down Expand Up @@ -116,13 +116,14 @@ export default class AppPermission extends React.Component<IProps, IState> {
</div>
);
const warningTooltip = (
<TextWithTooltip
tooltip={warningTooltipText}
tooltipClass="mx_Tooltip--appPermission mx_Tooltip--appPermission--dark"
class="mx_TextWithTooltip_target--helpIcon"
<TooltipTarget
label={warningTooltipText}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses a ReactNode and not a pair of strings so will need Compound/Design work to be supported

tooltipClassName="mx_Tooltip--appPermission mx_Tooltip--appPermission--dark"
tooltipTargetClassName="mx_TextWithTooltip_target mx_TextWithTooltip_target--helpIcon"
className="mx_TextWithTooltip_tooltip"
>
<HelpIcon className="mx_Icon mx_Icon_12" />
</TextWithTooltip>
</TooltipTarget>
);

// Due to i18n limitations, we can't dedupe the code for variables in these two messages.
Expand Down
31 changes: 13 additions & 18 deletions src/components/views/elements/InfoTooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,47 +17,42 @@ limitations under the License.

import React, { ReactNode } from "react";
import classNames from "classnames";
import { Tooltip } from "@vector-im/compound-web";

import { Alignment } from "./Tooltip";
import { _t } from "../../../languageHandler";
import TooltipTarget from "./TooltipTarget";

export enum InfoTooltipKind {
Info = "info",
Warning = "warning",
}

interface ITooltipProps {
tooltip?: React.ReactNode;
interface TooltipProps {
tooltip?: string;
className?: string;
tooltipClassName?: string;
kind?: InfoTooltipKind;
children?: ReactNode;
tabIndex?: number;
}

export default class InfoTooltip extends React.PureComponent<ITooltipProps> {
public constructor(props: ITooltipProps) {
export default class InfoTooltip extends React.PureComponent<TooltipProps> {
public constructor(props: TooltipProps) {
super(props);
}

public render(): React.ReactNode {
const { tooltip, children, tooltipClassName, className, kind } = this.props;
const { tooltip, children, className, kind } = this.props;
const title = _t("info_tooltip_title");
const iconClassName =
kind !== InfoTooltipKind.Warning ? "mx_InfoTooltip_icon_info" : "mx_InfoTooltip_icon_warning";

// Tooltip are forced on the right for a more natural feel to them on info icons
return (
<TooltipTarget
tooltipTargetClassName={classNames("mx_InfoTooltip", className)}
className="mx_InfoTooltip_container"
tooltipClassName={classNames("mx_InfoTooltip_tooltip", tooltipClassName)}
label={tooltip || title}
alignment={Alignment.Right}
>
<span className={classNames("mx_InfoTooltip_icon", iconClassName)} aria-label={title} />
{children}
</TooltipTarget>
<Tooltip label={tooltip || title} side="right">
<div className={classNames("mx_InfoTooltip", className)} tabIndex={this.props.tabIndex ?? 0}>
<span className={classNames("mx_InfoTooltip_icon", iconClassName)} aria-label={title} />
{children}
</div>
</Tooltip>
);
}
}
2 changes: 1 addition & 1 deletion src/components/views/elements/ServerPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ const ServerPicker: React.FC<IProps> = ({ title, dialogTitle, serverConfig, onSe
let serverName: React.ReactNode = serverConfig.isNameResolvable ? serverConfig.hsName : serverConfig.hsUrl;
if (serverConfig.hsNameIsDifferent) {
serverName = (
<TextWithTooltip class="mx_Login_underlinedServerName" tooltip={serverConfig.hsUrl}>
<TextWithTooltip className="mx_Login_underlinedServerName" tooltip={serverConfig.hsUrl}>
{serverConfig.hsName}
</TextWithTooltip>
);
Expand Down
31 changes: 11 additions & 20 deletions src/components/views/elements/TextWithTooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,13 @@
*/

import React, { HTMLAttributes } from "react";
import classNames from "classnames";

import TooltipTarget from "./TooltipTarget";
import { Tooltip } from "@vector-im/compound-web";

interface IProps extends HTMLAttributes<HTMLSpanElement> {
class?: string;
tooltipClass?: string;
tooltip: React.ReactNode;
tooltipProps?: Omit<React.ComponentProps<typeof TooltipTarget>, "label" | "tooltipClassName" | "className">;
onClick?: (ev: React.MouseEvent) => void;
tooltip: string;
tooltipProps?: {
tabIndex?: number;
};
}

export default class TextWithTooltip extends React.Component<IProps> {
Expand All @@ -33,20 +30,14 @@ export default class TextWithTooltip extends React.Component<IProps> {
}

public render(): React.ReactNode {
const { class: className, children, tooltip, tooltipClass, tooltipProps, ...props } = this.props;
const { className, children, tooltip, tooltipProps } = this.props;

return (
<TooltipTarget
onClick={this.props.onClick}
tooltipTargetClassName={classNames("mx_TextWithTooltip_target", className)}
{...tooltipProps}
label={tooltip}
tooltipClassName={tooltipClass}
className="mx_TextWithTooltip_tooltip"
{...props}
>
{children}
</TooltipTarget>
<Tooltip label={tooltip} side="right">
<div className={className} tabIndex={tooltipProps?.tabIndex ?? 0}>
{children}
</div>
</Tooltip>
);
}
}
3 changes: 0 additions & 3 deletions src/components/views/rooms/RoomList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@ const DmAuxButton: React.FC<IAuxButtonProps> = ({ tabIndex, dispatcher = default
tabIndex={tabIndex}
onClick={openMenu}
className="mx_RoomSublist_auxButton"
tooltipClassName="mx_RoomSublist_addRoomTooltip"
aria-label={_t("action|add_people")}
title={_t("action|add_people")}
isExpanded={menuDisplayed}
Expand All @@ -189,7 +188,6 @@ const DmAuxButton: React.FC<IAuxButtonProps> = ({ tabIndex, dispatcher = default
PosthogTrackers.trackInteraction("WebRoomListRoomsSublistPlusMenuCreateChatItem", e);
}}
className="mx_RoomSublist_auxButton"
tooltipClassName="mx_RoomSublist_addRoomTooltip"
aria-label={_t("action|start_chat")}
title={_t("action|start_chat")}
/>
Expand Down Expand Up @@ -355,7 +353,6 @@ const UntaggedAuxButton: React.FC<IAuxButtonProps> = ({ tabIndex }) => {
tabIndex={tabIndex}
onClick={openMenu}
className="mx_RoomSublist_auxButton"
tooltipClassName="mx_RoomSublist_addRoomTooltip"
aria-label={_t("room_list|add_room_label")}
title={_t("room_list|add_room_label")}
isExpanded={menuDisplayed}
Expand Down
2 changes: 1 addition & 1 deletion src/toasts/IncomingCallToast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ function JoinCallButtonWithCall({ onClick, call }: JoinCallButtonWithCallProps):
className="mx_IncomingCallToast_joinButton"
onClick={onClick}
disabled={disabledTooltip !== null}
tooltip={disabledTooltip}
tooltip={disabledTooltip ?? undefined}
kind="primary"
>
{_t("action|join")}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
<div
aria-disabled="true"
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_danger_outline mx_AccessibleButton_disabled"
data-state="closed"
disabled=""
role="button"
tabindex="0"
Expand All @@ -42,6 +43,7 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
<div
aria-disabled="true"
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_primary_outline mx_AccessibleButton_disabled"
data-state="closed"
disabled=""
role="button"
tabindex="0"
Expand Down Expand Up @@ -321,21 +323,21 @@ exports[`SpaceHierarchy <SpaceHierarchy /> renders 1`] = `
Join
</div>
<div
aria-describedby="mx_TooltipTarget_EetmBG4y"
class="mx_TextWithTooltip_target"
class=""
data-state="closed"
tabindex="0"
>
<span
class="mx_Checkbox mx_Checkbox_hasKind mx_Checkbox_kind_solid"
>
<input
disabled=""
id="checkbox_VCeEefiPqp"
id="checkbox_EetmBG4yVC"
tabindex="-1"
type="checkbox"
/>
<label
for="checkbox_VCeEefiPqp"
for="checkbox_EetmBG4yVC"
>
<div
class="mx_Checkbox_background"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ exports[`<ServerPickerDialog /> should render dialog 1`] = `
class="mx_StyledRadioButton_content"
>
<div
aria-describedby="mx_TooltipTarget_vY7Q4uEh"
class="mx_TextWithTooltip_target mx_Login_underlinedServerName"
class="mx_Login_underlinedServerName"
data-state="closed"
tabindex="0"
>
matrix.org
Expand Down
Loading