Tooltip: Use AccessibleButton in RovingAccessibleTooltipButton (#12458)

* Use `AccessibleButton` in `RovingAccessibleTooltipButton`

* Update snapshots

* Update @vector-im/compound-web

* Update playwright

* Remove placement
This commit is contained in:
Florian Duros 2024-04-30 11:35:58 +02:00 committed by GitHub
parent 3634e665b1
commit 2df946b5b1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 34 additions and 49 deletions

View file

@ -76,7 +76,7 @@
"@sentry/browser": "^7.0.0", "@sentry/browser": "^7.0.0",
"@testing-library/react-hooks": "^8.0.1", "@testing-library/react-hooks": "^8.0.1",
"@vector-im/compound-design-tokens": "^1.2.0", "@vector-im/compound-design-tokens": "^1.2.0",
"@vector-im/compound-web": "^4.0.2", "@vector-im/compound-web": "^4.1.0",
"@zxcvbn-ts/core": "^3.0.4", "@zxcvbn-ts/core": "^3.0.4",
"@zxcvbn-ts/language-common": "^3.0.4", "@zxcvbn-ts/language-common": "^3.0.4",
"@zxcvbn-ts/language-en": "^3.0.2", "@zxcvbn-ts/language-en": "^3.0.2",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

View file

@ -16,18 +16,15 @@ limitations under the License.
import React, { ComponentProps } from "react"; import React, { ComponentProps } from "react";
import AccessibleTooltipButton from "../../components/views/elements/AccessibleTooltipButton";
import { useRovingTabIndex } from "../RovingTabIndex"; import { useRovingTabIndex } from "../RovingTabIndex";
import { Ref } from "./types"; import { Ref } from "./types";
import AccessibleButton from "../../components/views/elements/AccessibleButton";
type Props<T extends keyof JSX.IntrinsicElements> = Omit< type Props<T extends keyof JSX.IntrinsicElements> = Omit<ComponentProps<typeof AccessibleButton<T>>, "tabIndex"> & {
ComponentProps<typeof AccessibleTooltipButton<T>>,
"tabIndex"
> & {
inputRef?: Ref; inputRef?: Ref;
}; };
// Wrapper to allow use of useRovingTabIndex for simple AccessibleTooltipButtons outside of React Functional Components. // Wrapper to allow use of useRovingTabIndex for simple AccessibleButtons outside of React Functional Components.
export const RovingAccessibleTooltipButton = <T extends keyof JSX.IntrinsicElements>({ export const RovingAccessibleTooltipButton = <T extends keyof JSX.IntrinsicElements>({
inputRef, inputRef,
onFocus, onFocus,
@ -35,7 +32,7 @@ export const RovingAccessibleTooltipButton = <T extends keyof JSX.IntrinsicEleme
}: Props<T>): JSX.Element => { }: Props<T>): JSX.Element => {
const [onFocusInternal, isActive, ref] = useRovingTabIndex(inputRef); const [onFocusInternal, isActive, ref] = useRovingTabIndex(inputRef);
return ( return (
<AccessibleTooltipButton <AccessibleButton
{...props} {...props}
onFocus={(event: React.FocusEvent) => { onFocus={(event: React.FocusEvent) => {
onFocusInternal(); onFocusInternal();

View file

@ -229,22 +229,16 @@ const ReplyInThreadButton: React.FC<IReplyInThreadButton> = ({ mxEvent }) => {
} }
}; };
const title = !hasARelation ? _t("action|reply_in_thread") : _t("threads|error_start_thread_existing_relation");
return ( return (
<RovingAccessibleTooltipButton <RovingAccessibleTooltipButton
className="mx_MessageActionBar_iconButton mx_MessageActionBar_threadButton" className="mx_MessageActionBar_iconButton mx_MessageActionBar_threadButton"
disabled={hasARelation} disabled={hasARelation}
tooltip={ title={title}
<>
<div className="mx_Tooltip_title">
{!hasARelation
? _t("action|reply_in_thread")
: _t("threads|error_start_thread_existing_relation")}
</div>
</>
}
title={!hasARelation ? _t("action|reply_in_thread") : _t("threads|error_start_thread_existing_relation")}
onClick={onClick} onClick={onClick}
onContextMenu={onClick} onContextMenu={onClick}
placement="left"
> >
<ThreadIcon /> <ThreadIcon />
</RovingAccessibleTooltipButton> </RovingAccessibleTooltipButton>
@ -509,18 +503,7 @@ export default class MessageActionBar extends React.PureComponent<IMessageAction
mx_MessageActionBar_iconButton: true, mx_MessageActionBar_iconButton: true,
mx_MessageActionBar_expandCollapseMessageButton: true, mx_MessageActionBar_expandCollapseMessageButton: true,
}); });
const tooltip = (
<>
<div className="mx_Tooltip_title">
{this.props.isQuoteExpanded
? _t("timeline|mab|collapse_reply_chain")
: _t("timeline|mab|expand_reply_chain")}
</div>
<div className="mx_Tooltip_sub">
{_t(ALTERNATE_KEY_NAME[Key.SHIFT]) + " + " + _t("action|click")}
</div>
</>
);
toolbarOpts.push( toolbarOpts.push(
<RovingAccessibleTooltipButton <RovingAccessibleTooltipButton
className={expandClassName} className={expandClassName}
@ -529,9 +512,10 @@ export default class MessageActionBar extends React.PureComponent<IMessageAction
? _t("timeline|mab|collapse_reply_chain") ? _t("timeline|mab|collapse_reply_chain")
: _t("timeline|mab|expand_reply_chain") : _t("timeline|mab|expand_reply_chain")
} }
tooltip={tooltip} caption={_t(ALTERNATE_KEY_NAME[Key.SHIFT]) + " + " + _t("action|click")}
onClick={this.props.toggleThreadExpanded} onClick={this.props.toggleThreadExpanded}
key="expand" key="expand"
placement="left"
> >
{this.props.isQuoteExpanded ? <CollapseMessageIcon /> : <ExpandMessageIcon />} {this.props.isQuoteExpanded ? <CollapseMessageIcon /> : <ExpandMessageIcon />}
</RovingAccessibleTooltipButton>, </RovingAccessibleTooltipButton>,

View file

@ -34,7 +34,6 @@ import { WidgetType } from "../../../widgets/WidgetType";
import { WidgetMessagingStore } from "../../../stores/widgets/WidgetMessagingStore"; import { WidgetMessagingStore } from "../../../stores/widgets/WidgetMessagingStore";
import WidgetUtils from "../../../utils/WidgetUtils"; import WidgetUtils from "../../../utils/WidgetUtils";
import { ElementWidgetActions } from "../../../stores/widgets/ElementWidgetActions"; import { ElementWidgetActions } from "../../../stores/widgets/ElementWidgetActions";
import { Alignment } from "../elements/Tooltip";
interface Props { interface Props {
widgetId: string; widgetId: string;
@ -128,9 +127,9 @@ export const WidgetPip: FC<Props> = ({ widgetId, room, viewingRoom, onStartMovin
<Toolbar className="mx_WidgetPip_footer"> <Toolbar className="mx_WidgetPip_footer">
<RovingAccessibleTooltipButton <RovingAccessibleTooltipButton
onClick={onLeaveClick} onClick={onLeaveClick}
tooltip={_t("action|leave")} title={_t("action|leave")}
aria-label={_t("action|leave")} aria-label={_t("action|leave")}
alignment={Alignment.Top} placement="top"
> >
<HangupIcon className="mx_Icon mx_Icon_24" /> <HangupIcon className="mx_Icon mx_Icon_24" />
</RovingAccessibleTooltipButton> </RovingAccessibleTooltipButton>

View file

@ -127,16 +127,6 @@ interface IFormatButtonProps {
class FormatButton extends React.PureComponent<IFormatButtonProps> { class FormatButton extends React.PureComponent<IFormatButtonProps> {
public render(): React.ReactNode { public render(): React.ReactNode {
const className = `mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIcon${this.props.icon}`; const className = `mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIcon${this.props.icon}`;
let shortcut;
if (this.props.shortcut) {
shortcut = <div className="mx_MessageComposerFormatBar_tooltipShortcut">{this.props.shortcut}</div>;
}
const tooltip = (
<div>
<div className="mx_Tooltip_title">{this.props.label}</div>
<div className="mx_Tooltip_sub">{shortcut}</div>
</div>
);
// element="button" and type="button" are necessary for the buttons to work on WebKit, // element="button" and type="button" are necessary for the buttons to work on WebKit,
// otherwise the text is deselected before onClick can ever be called // otherwise the text is deselected before onClick can ever be called
@ -145,8 +135,9 @@ class FormatButton extends React.PureComponent<IFormatButtonProps> {
element="button" element="button"
type="button" type="button"
onClick={this.props.onClick} onClick={this.props.onClick}
aria-label={this.props.label}
title={this.props.label} title={this.props.label}
tooltip={tooltip} caption={this.props.shortcut}
className={className} className={className}
/> />
); );

View file

@ -397,6 +397,7 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
<button <button
aria-label="Bold" aria-label="Bold"
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconBold" class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconBold"
data-state="closed"
role="button" role="button"
tabindex="0" tabindex="0"
type="button" type="button"
@ -404,6 +405,7 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
<button <button
aria-label="Italics" aria-label="Italics"
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconItalic" class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconItalic"
data-state="closed"
role="button" role="button"
tabindex="-1" tabindex="-1"
type="button" type="button"
@ -411,6 +413,7 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
<button <button
aria-label="Strikethrough" aria-label="Strikethrough"
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconStrikethrough" class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconStrikethrough"
data-state="closed"
role="button" role="button"
tabindex="-1" tabindex="-1"
type="button" type="button"
@ -418,6 +421,7 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
<button <button
aria-label="Code block" aria-label="Code block"
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconCode" class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconCode"
data-state="closed"
role="button" role="button"
tabindex="-1" tabindex="-1"
type="button" type="button"
@ -425,6 +429,7 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
<button <button
aria-label="Quote" aria-label="Quote"
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconQuote" class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconQuote"
data-state="closed"
role="button" role="button"
tabindex="-1" tabindex="-1"
type="button" type="button"
@ -432,6 +437,7 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
<button <button
aria-label="Insert link" aria-label="Insert link"
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconInsertLink" class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconInsertLink"
data-state="closed"
role="button" role="button"
tabindex="-1" tabindex="-1"
type="button" type="button"
@ -644,6 +650,7 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
<button <button
aria-label="Bold" aria-label="Bold"
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconBold" class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconBold"
data-state="closed"
role="button" role="button"
tabindex="0" tabindex="0"
type="button" type="button"
@ -651,6 +658,7 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
<button <button
aria-label="Italics" aria-label="Italics"
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconItalic" class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconItalic"
data-state="closed"
role="button" role="button"
tabindex="-1" tabindex="-1"
type="button" type="button"
@ -658,6 +666,7 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
<button <button
aria-label="Strikethrough" aria-label="Strikethrough"
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconStrikethrough" class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconStrikethrough"
data-state="closed"
role="button" role="button"
tabindex="-1" tabindex="-1"
type="button" type="button"
@ -665,6 +674,7 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
<button <button
aria-label="Code block" aria-label="Code block"
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconCode" class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconCode"
data-state="closed"
role="button" role="button"
tabindex="-1" tabindex="-1"
type="button" type="button"
@ -672,6 +682,7 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
<button <button
aria-label="Quote" aria-label="Quote"
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconQuote" class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconQuote"
data-state="closed"
role="button" role="button"
tabindex="-1" tabindex="-1"
type="button" type="button"
@ -679,6 +690,7 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
<button <button
aria-label="Insert link" aria-label="Insert link"
class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconInsertLink" class="mx_AccessibleButton mx_MessageComposerFormatBar_button mx_MessageComposerFormatBar_buttonIconInsertLink"
data-state="closed"
role="button" role="button"
tabindex="-1" tabindex="-1"
type="button" type="button"

View file

@ -11,6 +11,7 @@ exports[`EventTileThreadToolbar renders 1`] = `
<div <div
aria-label="View in room" aria-label="View in room"
class="mx_AccessibleButton mx_MessageActionBar_iconButton" class="mx_AccessibleButton mx_MessageActionBar_iconButton"
data-state="closed"
role="button" role="button"
tabindex="0" tabindex="0"
> >
@ -19,6 +20,7 @@ exports[`EventTileThreadToolbar renders 1`] = `
<div <div
aria-label="Copy link to thread" aria-label="Copy link to thread"
class="mx_AccessibleButton mx_MessageActionBar_iconButton" class="mx_AccessibleButton mx_MessageActionBar_iconButton"
data-state="closed"
role="button" role="button"
tabindex="-1" tabindex="-1"
> >

View file

@ -3060,10 +3060,10 @@
dependencies: dependencies:
svg2vectordrawable "^2.9.1" svg2vectordrawable "^2.9.1"
"@vector-im/compound-web@^4.0.2": "@vector-im/compound-web@^4.1.0":
version "4.0.2" version "4.1.0"
resolved "https://registry.yarnpkg.com/@vector-im/compound-web/-/compound-web-4.0.2.tgz#cd89ca076b9b0528718e45110a4c8126e7556c63" resolved "https://registry.yarnpkg.com/@vector-im/compound-web/-/compound-web-4.1.0.tgz#45fa22e4e91b5fd4c2f535e040072990d5a33712"
integrity sha512-MBqmSbtcWC6KJjuTWPZ6FYc83YrUJ9dOageUdbayjhVGZ/de/a+nl/vPIAX+5ic2QWUN7nn9hujfzQF69mbIeg== integrity sha512-FQSJK7PaJ3dR1c1Q3TYVSShJBl9TwlrhKadnTWsPIX6xE+rvCAeujE50QbcEWdDlWeaJ9Hi0bVPlEssJ+eRwtQ==
dependencies: dependencies:
"@floating-ui/react" "^0.26.9" "@floating-ui/react" "^0.26.9"
"@floating-ui/react-dom" "^2.0.8" "@floating-ui/react-dom" "^2.0.8"