diff --git a/src/components/views/auth/InteractiveAuthEntryComponents.tsx b/src/components/views/auth/InteractiveAuthEntryComponents.tsx
index 2bc0fe80db9..7bed60d6037 100644
--- a/src/components/views/auth/InteractiveAuthEntryComponents.tsx
+++ b/src/components/views/auth/InteractiveAuthEntryComponents.tsx
@@ -26,10 +26,8 @@ import SettingsStore from "../../../settings/SettingsStore";
import { LocalisedPolicy, Policies } from "../../../Terms";
import { AuthHeaderModifier } from "../../structures/auth/header/AuthHeaderModifier";
import AccessibleButton, { AccessibleButtonKind, ButtonEvent } from "../elements/AccessibleButton";
-import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
import Field from "../elements/Field";
import Spinner from "../elements/Spinner";
-import { Alignment } from "../elements/Tooltip";
import CaptchaForm from "./CaptchaForm";
/* This file contains a collection of components which are used by the
@@ -501,15 +499,16 @@ export class EmailIdentityAuthEntry extends React.Component<
{},
{
a: (text: string) => (
- this.setState({ requested: false })
+ ? (open) => {
+ if (!open) this.setState({ requested: false });
+ }
: undefined
}
onClick={async (): Promise => {
@@ -524,7 +523,7 @@ export class EmailIdentityAuthEntry extends React.Component<
}}
>
{text}
-
+
),
},
)}
diff --git a/src/components/views/beta/BetaCard.tsx b/src/components/views/beta/BetaCard.tsx
index 84c7a27fe0f..7d17c3af941 100644
--- a/src/components/views/beta/BetaCard.tsx
+++ b/src/components/views/beta/BetaCard.tsx
@@ -27,7 +27,6 @@ import SdkConfig from "../../../SdkConfig";
import SettingsFlag from "../elements/SettingsFlag";
import { useFeatureEnabled } from "../../../hooks/useSettings";
import InlineSpinner from "../elements/InlineSpinner";
-import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
import { shouldShowFeedback } from "../../../utils/Feedback";
// XXX: Keep this around for re-use in future Betas
@@ -50,19 +49,15 @@ export const BetaPill: React.FC = ({
}) => {
if (onClick) {
return (
-
-
{tooltipTitle}
-
{tooltipCaption}
-
- }
+ aria-label={`${tooltipTitle} ${tooltipCaption}`}
+ title={tooltipTitle}
+ caption={tooltipCaption}
onClick={onClick}
>
{_t("common|beta")}
-
+
);
}
diff --git a/src/components/views/elements/AccessibleTooltipButton.tsx b/src/components/views/elements/AccessibleTooltipButton.tsx
deleted file mode 100644
index 759643da1cc..00000000000
--- a/src/components/views/elements/AccessibleTooltipButton.tsx
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
-Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
-Copyright 2019 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-import React, { SyntheticEvent, FocusEvent, forwardRef, useEffect, Ref, useState, ComponentProps } from "react";
-
-import AccessibleButton from "./AccessibleButton";
-import Tooltip, { Alignment } from "./Tooltip";
-
-/**
- * Type of props accepted by {@link AccessibleTooltipButton}.
- *
- * Extends that of {@link AccessibleButton}.
- */
-type Props = ComponentProps> & {
- /**
- * Title to show in the tooltip and use as aria-label
- */
- title?: string;
- /**
- * Tooltip node to show in the tooltip, takes precedence over `title`
- */
- tooltip?: React.ReactNode;
- /**
- * Trigger label to render
- */
- label?: string;
- /**
- * Classname to apply to the tooltip
- */
- tooltipClassName?: string;
- /**
- * Force the tooltip to be hidden
- */
- forceHide?: boolean;
- /**
- * Alignment to render the tooltip with
- */
- alignment?: Alignment;
- /**
- * Function to call when the children are hovered over
- */
- onHover?: (hovering: boolean) => void;
- /**
- * Function to call when the tooltip goes from shown to hidden.
- */
- onHideTooltip?(ev: SyntheticEvent): void;
-};
-
-/**
- * @deprecated use AccessibleButton with `title` and `caption` instead.
- */
-const AccessibleTooltipButton = forwardRef(function (
- { title, tooltip, children, forceHide, alignment, onHideTooltip, tooltipClassName, element, ...props }: Props,
- ref: Ref,
-) {
- const [hover, setHover] = useState(false);
-
- useEffect(() => {
- // If forceHide is set then force hover to off to hide the tooltip
- if (forceHide && hover) {
- setHover(false);
- }
- }, [forceHide, hover]);
-
- const showTooltip = (): void => {
- props.onHover?.(true);
- if (forceHide) return;
- setHover(true);
- };
-
- const hideTooltip = (ev: SyntheticEvent): void => {
- props.onHover?.(false);
- setHover(false);
- onHideTooltip?.(ev);
- };
-
- const onFocus = (ev: FocusEvent): void => {
- // We only show the tooltip if focus arrived here from some other
- // element, to avoid leaving tooltips hanging around when a modal closes
- if (ev.relatedTarget) showTooltip();
- };
-
- const tip = hover && (title || tooltip) && (
-
- );
- return (
-
- {children}
- {props.label}
- {(tooltip || title) && tip}
-
- );
-});
-
-export default AccessibleTooltipButton;
diff --git a/src/components/views/settings/devices/DeviceExpandDetailsButton.tsx b/src/components/views/settings/devices/DeviceExpandDetailsButton.tsx
index 317afdfca15..791b6125917 100644
--- a/src/components/views/settings/devices/DeviceExpandDetailsButton.tsx
+++ b/src/components/views/settings/devices/DeviceExpandDetailsButton.tsx
@@ -19,10 +19,10 @@ import React, { ComponentProps } from "react";
import { Icon as CaretIcon } from "../../../../../res/img/feather-customised/dropdown-arrow.svg";
import { _t } from "../../../../languageHandler";
-import AccessibleTooltipButton from "../../elements/AccessibleTooltipButton";
+import AccessibleButton from "../../elements/AccessibleButton";
type Props = Omit<
- ComponentProps>,
+ ComponentProps>,
"aria-label" | "title" | "kind" | "className" | "onClick" | "element"
> & {
isExpanded: boolean;
@@ -36,7 +36,7 @@ export const DeviceExpandDetailsButton =
}: Props): JSX.Element => {
const label = isExpanded ? _t("settings|sessions|hide_details") : _t("settings|sessions|show_details");
return (
-
onClick={onClick}
>
-
+
);
};
diff --git a/test/components/views/auth/InteractiveAuthEntryComponents-test.tsx b/test/components/views/auth/InteractiveAuthEntryComponents-test.tsx
new file mode 100644
index 00000000000..e6e3e1383e3
--- /dev/null
+++ b/test/components/views/auth/InteractiveAuthEntryComponents-test.tsx
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2024 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from "react";
+import { render, screen, waitFor, act } from "@testing-library/react";
+import { AuthType } from "matrix-js-sdk/src/interactive-auth";
+import userEvent from "@testing-library/user-event";
+
+import { EmailIdentityAuthEntry } from "../../../../src/components/views/auth/InteractiveAuthEntryComponents";
+import { createTestClient } from "../../../test-utils";
+
+describe("", () => {
+ const renderIdentityAuth = () => {
+ const matrixClient = createTestClient();
+
+ return render(
+ ,
+ );
+ };
+
+ test("should render", () => {
+ const { container } = renderIdentityAuth();
+ expect(container).toMatchSnapshot();
+ });
+
+ test("should clear the requested state when the button tooltip is hidden", async () => {
+ renderIdentityAuth();
+
+ // After a click on the resend button, the button should display the resent label
+ screen.getByRole("button", { name: "Resend" }).click();
+ await waitFor(() => expect(screen.queryByRole("button", { name: "Resent!" })).toBeInTheDocument());
+ expect(screen.queryByRole("button", { name: "Resend" })).toBeNull();
+
+ const resentButton = screen.getByRole("button", { name: "Resent!" });
+ // Hover briefly the button and wait for the tooltip to be displayed
+ await userEvent.hover(resentButton);
+ await waitFor(() => expect(screen.getByRole("tooltip", { name: "Resent!" })).toBeInTheDocument());
+
+ // On unhover, it should display again the resend button
+ await act(() => userEvent.unhover(resentButton));
+ await waitFor(() => expect(screen.queryByRole("button", { name: "Resend" })).toBeInTheDocument());
+ });
+});
diff --git a/test/components/views/auth/__snapshots__/InteractiveAuthEntryComponents-test.tsx.snap b/test/components/views/auth/__snapshots__/InteractiveAuthEntryComponents-test.tsx.snap
new file mode 100644
index 00000000000..65f86a35d2a
--- /dev/null
+++ b/test/components/views/auth/__snapshots__/InteractiveAuthEntryComponents-test.tsx.snap
@@ -0,0 +1,34 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[` should render 1`] = `
+
+
+
+
+ To create your account, open the link in the email we just sent to
+
+ alice@example.xyz
+
+ .
+
+