Upgrade to latest compound-web package (#84)

* Upgrade to latest compound-web package

* Use a custom render function for jest tests

This way we don't need to manually wrap our components with
<TooltipProvider>

* Pin wrap-ansi to fix broken yarn install

* Add playwright helper to find tooltip from element

and use it in the failing test

* Exclude floating-ui divs/spans from axe testing

This is rendered outside .MatrixChat by compound and contains all the
tooltips.

* Wrap outermost components with TooltipProvider

* Remove onChange and use onSelect for toggle

* Fix jest tests and update snapshots

* Use vector-im/matrix-wysiwig

---------

Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
R Midhun Suresh 2024-10-14 21:41:58 +05:30 committed by GitHub
parent 3bc0439fd2
commit 91e84f7951
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
389 changed files with 1261 additions and 1084 deletions

View file

@ -12,6 +12,7 @@ import React, { CSSProperties, RefObject, SyntheticEvent, useRef, useState } fro
import ReactDOM from "react-dom";
import classNames from "classnames";
import FocusLock from "react-focus-lock";
import { TooltipProvider } from "@vector-im/compound-web";
import { Writeable } from "../../@types/common";
import UIStore from "../../stores/UIStore";
@ -621,15 +622,17 @@ export function createMenu(
};
const menu = (
<ContextMenu
{...props}
mountAsChild={true}
hasBackground={false}
onFinished={onFinished} // eslint-disable-line react/jsx-no-bind
windowResize={onFinished} // eslint-disable-line react/jsx-no-bind
>
<ElementClass {...props} onFinished={onFinished} />
</ContextMenu>
<TooltipProvider>
<ContextMenu
{...props}
mountAsChild={true}
hasBackground={false}
onFinished={onFinished} // eslint-disable-line react/jsx-no-bind
windowResize={onFinished} // eslint-disable-line react/jsx-no-bind
>
<ElementClass {...props} onFinished={onFinished} />
</ContextMenu>
</TooltipProvider>
);
ReactDOM.render(menu, getOrCreateContainer());

View file

@ -24,6 +24,7 @@ import { logger } from "matrix-js-sdk/src/logger";
import { throttle } from "lodash";
import { CryptoEvent } from "matrix-js-sdk/src/crypto";
import { KeyBackupInfo } from "matrix-js-sdk/src/crypto-api";
import { TooltipProvider } from "@vector-im/compound-web";
// what-input helps improve keyboard accessibility
import "what-input";
@ -2181,7 +2182,9 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
return (
<ErrorBoundary>
<SDKContext.Provider value={this.stores}>{view}</SDKContext.Provider>
<SDKContext.Provider value={this.stores}>
<TooltipProvider>{view}</TooltipProvider>
</SDKContext.Provider>
</ErrorBoundary>
);
}

View file

@ -130,7 +130,7 @@ export const ThreadPanelHeader: React.FC<{
return (
<div className="mx_BaseCard_header_title">
<Tooltip label={_t("threads|mark_all_read")}>
<IconButton onClick={onMarkAllThreadsReadClick} aria-label={_t("threads|mark_all_read")} size="24px">
<IconButton onClick={onMarkAllThreadsReadClick} size="24px">
<MarkAllThreadsReadIcon />
</IconButton>
</Tooltip>

View file

@ -58,7 +58,7 @@ export const CheckEmail: React.FC<CheckEmailProps> = ({
<input onClick={onSubmitForm} type="button" className="mx_Login_submit" value={_t("action|next")} />
<div className="mx_AuthBody_did-not-receive">
<span className="mx_VerifyEMailDialog_text-light">{_t("auth|check_email_resend_prompt")}</span>
<Tooltip label={_t("auth|check_email_resend_tooltip")} placement="top" open={tooltipVisible}>
<Tooltip description={_t("auth|check_email_resend_tooltip")} placement="top" open={tooltipVisible}>
<AccessibleButton className="mx_AuthBody_resend-button" kind="link" onClick={onResendClickFn}>
<RetryIcon className="mx_Icon mx_Icon_16" />
{_t("action|resend")}

View file

@ -57,7 +57,7 @@ export const VerifyEmailModal: React.FC<Props> = ({
<div className="mx_AuthBody_did-not-receive">
<span className="mx_VerifyEMailDialog_text-light">{_t("auth|check_email_resend_prompt")}</span>
<Tooltip label={_t("auth|check_email_resend_tooltip")} placement="top" open={tooltipVisible}>
<Tooltip description={_t("auth|check_email_resend_tooltip")} placement="top" open={tooltipVisible}>
<AccessibleButton className="mx_AuthBody_resend-button" kind="link" onClick={onResendClickFn}>
<RetryIcon className="mx_Icon mx_Icon_16" />
{_t("action|resend")}

View file

@ -212,7 +212,7 @@ const AccessibleButton = forwardRef(function <T extends keyof JSX.IntrinsicEleme
if (title) {
return (
<Tooltip
label={title}
description={title}
caption={caption}
isTriggerInteractive={true}
placement={placement}

View file

@ -35,7 +35,7 @@ export default class InfoTooltip extends React.PureComponent<TooltipProps> {
// Tooltip are forced on the right for a more natural feel to them on info icons
return (
<Tooltip label={tooltip || title} placement="right">
<Tooltip description={tooltip || title} placement="right">
<div className={classNames("mx_InfoTooltip", className)} tabIndex={this.props.tabIndex ?? 0}>
<span className={classNames("mx_InfoTooltip_icon", iconClassName)} aria-label={title} />
{children}

View file

@ -8,6 +8,7 @@ Please see LICENSE files in the repository root for full details.
import React, { MutableRefObject, ReactNode } from "react";
import ReactDOM from "react-dom";
import { isNullOrUndefined } from "matrix-js-sdk/src/utils";
import { TooltipProvider } from "@vector-im/compound-web";
import dis from "../../../dispatcher/dispatcher";
import MatrixClientContext from "../../../contexts/MatrixClientContext";
@ -167,9 +168,11 @@ export default class PersistedElement extends React.Component<IProps> {
private renderApp(): void {
const content = (
<MatrixClientContext.Provider value={MatrixClientPeg.safeGet()}>
<div ref={this.collectChild} style={this.props.style}>
{this.props.children}
</div>
<TooltipProvider>
<div ref={this.collectChild} style={this.props.style}>
{this.props.children}
</div>
</TooltipProvider>
</MatrixClientContext.Provider>
);

View file

@ -141,7 +141,7 @@ export const Pill: React.FC<PillProps> = ({ type: propType, url, inMessage, room
<bdi>
<MatrixClientContext.Provider value={MatrixClientPeg.safeGet()}>
<Tooltip
label={resourceId ?? ""}
description={resourceId ?? ""}
open={resourceId ? undefined : false}
placement="right"
isTriggerInteractive={isAnchor}

View file

@ -111,7 +111,7 @@ export default function RoomTopic({ room, className, ...props }: IProps): JSX.El
if (!body) return <div className={classNames(className, "mx_RoomTopic")} />;
return (
<Tooltip label={_t("room|read_topic")} disabled={disableTooltip}>
<Tooltip description={_t("room|read_topic")} disabled={disableTooltip}>
<div
{...props}
tabIndex={0}

View file

@ -61,7 +61,7 @@ export default class MStickerBody extends MImageBody {
return {
placement: "right",
label: content.body,
description: content.body,
};
}

View file

@ -53,7 +53,7 @@ export default class MessageTimestamp extends React.Component<IProps> {
}
return (
<Tooltip label={label} caption={caption}>
<Tooltip description={label} caption={caption}>
<span className="mx_MessageTimestamp" aria-hidden={true} aria-live="off">
{icon}
{timestamp}

View file

@ -51,7 +51,7 @@ export default class ReactionsRowButtonTooltip extends React.PureComponent<Props
const caption = shortName ? _t("timeline|reactions|tooltip_caption", { shortName }) : undefined;
return (
<Tooltip label={formattedSenders} caption={caption} placement="right">
<Tooltip description={formattedSenders} caption={caption} placement="right">
{children}
</Tooltip>
);

View file

@ -9,6 +9,7 @@ Please see LICENSE files in the repository root for full details.
import React, { createRef, SyntheticEvent, MouseEvent } from "react";
import ReactDOM from "react-dom";
import { MsgType } from "matrix-js-sdk/src/matrix";
import { TooltipProvider } from "@vector-im/compound-web";
import * as HtmlUtils from "../../../HtmlUtils";
import { formatDate } from "../../../DateUtils";
@ -335,7 +336,11 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
const reason = node.getAttribute("data-mx-spoiler") ?? undefined;
node.removeAttribute("data-mx-spoiler"); // we don't want to recurse
const spoiler = <Spoiler reason={reason} contentHtml={node.outerHTML} />;
const spoiler = (
<TooltipProvider>
<Spoiler reason={reason} contentHtml={node.outerHTML} />
</TooltipProvider>
);
ReactDOM.render(spoiler, spoilerContainer);
node.parentNode?.replaceChild(spoilerContainer, node);

View file

@ -373,9 +373,7 @@ const RoomSummaryCard: React.FC<IProps> = ({
Icon={FavouriteIcon}
label={_t("room|context_menu|favourite")}
checked={isFavorite}
onChange={() => tagRoom(room, DefaultTagID.Favourite)}
// XXX: https://github.com/element-hq/compound/issues/288
onSelect={() => {}}
onSelect={() => tagRoom(room, DefaultTagID.Favourite)}
/>
<MenuItem
Icon={UserAddIcon}

View file

@ -1555,7 +1555,7 @@ function SentReceipt({ messageState }: ISentReceiptProps): JSX.Element {
<div className="mx_EventTile_msgOption">
<div className="mx_ReadReceiptGroup">
<Tooltip label={label} placement="top-end">
<div className="mx_ReadReceiptGroup_button">
<div className="mx_ReadReceiptGroup_button" role="status">
<span className="mx_ReadReceiptGroup_container">
<span className={receiptClasses}>{nonCssBadge}</span>
</span>

View file

@ -666,7 +666,7 @@ export class MessageComposer extends React.Component<IProps, IState> {
});
return (
<Tooltip open={isTooltipOpen} label={formatTimeLeft(secondsLeft)} placement="top">
<Tooltip open={isTooltipOpen} description={formatTimeLeft(secondsLeft)} placement="bottom">
<div className={classes} ref={this.ref} role="region" aria-label={_t("a11y|message_composer")}>
{recordingTooltip}
<div className="mx_MessageComposer_wrapper">

View file

@ -211,7 +211,7 @@ export function ReadReceiptPerson({
onAfterClick,
}: ReadReceiptPersonProps): JSX.Element {
return (
<Tooltip label={roomMember?.rawDisplayName ?? userId} caption={userId} placement="top">
<Tooltip description={roomMember?.rawDisplayName ?? userId} caption={userId} placement="top">
<div>
<MenuItem
className="mx_ReadReceiptGroup_person"

View file

@ -205,7 +205,7 @@ export default function RoomHeader({
);
const closeLobbyButton = (
<Tooltip label={_t("voip|close_lobby")}>
<IconButton onClick={toggleCall} aria-label={_t("voip|close_lobby")}>
<IconButton onClick={toggleCall}>
<CloseCallIcon />
</IconButton>
</Tooltip>

View file

@ -80,7 +80,7 @@ export const CallGuestLinkButton: React.FC<{ room: Room }> = ({ room }) => {
<>
{canInviteGuests && (
<Tooltip label={_t("voip|get_call_link")}>
<IconButton onClick={shareClick} aria-label={_t("voip|get_call_link")}>
<IconButton onClick={shareClick}>
<ExternalLinkIcon />
</IconButton>
</Tooltip>