Fix various dialogs failing to open due to containing linked text (#34304)

* Wrap Dialog in LinkedTextContent

* actually use originalMxModuleApi

* lint

* fmt
This commit is contained in:
Will Hunt
2026-07-28 11:48:56 +00:00
committed by GitHub
parent 207727c481
commit df7924df02
2 changed files with 80 additions and 31 deletions
+44
View File
@@ -0,0 +1,44 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
// @vitest-environment happy-dom
import React from "react";
import { describe, it, expect, beforeEach, afterEach } from "vitest";
import { LinkedText } from "@element-hq/web-shared-components";
import { screen } from "test-utils-rtl";
import { flushPromises, stubClient } from "test-utils";
import type { I18nApi } from "@element-hq/web-shared-components";
import Modal from "./Modal";
import { type ModuleApi } from "./modules/Api";
function LinkedTextDialog({ onFinished }: { onFinished(): void }): React.JSX.Element {
return <LinkedText>Check out https://matrix.org for more info</LinkedText>;
}
describe("Modal", () => {
let originalMxModuleApi: ModuleApi;
beforeEach(() => {
stubClient();
// Required for the i18n context around the dialog to work.
originalMxModuleApi = window.mxModuleApi;
window.mxModuleApi = { i18n: {} as I18nApi } as ModuleApi;
});
afterEach(() => {
Modal.forceCloseAllModals();
window.mxModuleApi = originalMxModuleApi;
});
it("provides LinkedTextContext to dialogs rendered in the separate dialog root", async () => {
Modal.createDialog(LinkedTextDialog);
await flushPromises();
expect(screen.getByRole("link")).toBeInTheDocument();
});
});
+36 -31
View File
@@ -12,7 +12,7 @@ import { createRoot, type Root } from "react-dom/client";
import classNames from "classnames";
import { TypedEventEmitter } from "matrix-js-sdk/src/matrix";
import { Glass, TooltipProvider } from "@vector-im/compound-web";
import { I18nContext } from "@element-hq/web-shared-components";
import { I18nContext, LinkedTextContext } from "@element-hq/web-shared-components";
import defaultDispatcher from "./dispatcher/dispatcher";
import AsyncWrapper from "./AsyncWrapper";
@@ -20,6 +20,7 @@ import { type Defaultize } from "./@types/common";
import { type ActionPayload } from "./dispatcher/payloads";
import { filterBoolean } from "./utils/arrays.ts";
import { SDKContext } from "./contexts/SDKContext.ts";
import { LinkedTextConfiguration } from "./Linkify";
const DIALOG_CONTAINER_ID = "mx_Dialog_Container";
const STATIC_DIALOG_CONTAINER_ID = "mx_Dialog_StaticContainer";
@@ -439,22 +440,24 @@ export class ModalManager extends TypedEventEmitter<ModalManagerEvent, HandlerMa
const staticDialog = (
<StrictMode>
<SDKContext.Provider value={window.mxSdkContext}>
{/* Provide I18nContext for shared-components used inside dialogs rendered in a separate root. */}
{/* Provide I18nContext and LinkedTextContext for shared-components used inside dialogs rendered in a separate root. */}
<I18nContext.Provider value={window.mxModuleApi.i18n}>
<TooltipProvider>
<div className={classes}>
<Glass className="mx_Dialog_border">
<div className="mx_Dialog">{this.staticModal.elem}</div>
</Glass>
{/* We break the rule here as this is a mouse-only interaction */}
{/* oxlint-disable-next-line jsx-a11y/click-events-have-key-events */}
<div
data-testid="dialog-background"
className="mx_Dialog_background mx_Dialog_staticBackground"
onClick={this.onBackgroundClick}
/>
</div>
</TooltipProvider>
<LinkedTextContext.Provider value={LinkedTextConfiguration}>
<TooltipProvider>
<div className={classes}>
<Glass className="mx_Dialog_border">
<div className="mx_Dialog">{this.staticModal.elem}</div>
</Glass>
{/* We break the rule here as this is a mouse-only interaction */}
{/* oxlint-disable-next-line jsx-a11y/click-events-have-key-events */}
<div
data-testid="dialog-background"
className="mx_Dialog_background mx_Dialog_staticBackground"
onClick={this.onBackgroundClick}
/>
</div>
</TooltipProvider>
</LinkedTextContext.Provider>
</I18nContext.Provider>
</SDKContext.Provider>
</StrictMode>
@@ -475,22 +478,24 @@ export class ModalManager extends TypedEventEmitter<ModalManagerEvent, HandlerMa
const dialog = (
<StrictMode>
<SDKContext.Provider value={window.mxSdkContext}>
{/* Provide I18nContext for shared-components used inside dialogs rendered in a separate root. */}
{/* Provide I18nContext and LinkedTextContext for shared-components used inside dialogs rendered in a separate root. */}
<I18nContext.Provider value={window.mxModuleApi.i18n}>
<TooltipProvider>
<div className={classes}>
<Glass className="mx_Dialog_border">
<div className="mx_Dialog">{modal.elem}</div>
</Glass>
{/* We break the rule here as this is a mouse-only interaction */}
{/* oxlint-disable-next-line jsx-a11y/click-events-have-key-events */}
<div
data-testid="dialog-background"
className="mx_Dialog_background"
onClick={this.onBackgroundClick}
/>
</div>
</TooltipProvider>
<LinkedTextContext.Provider value={LinkedTextConfiguration}>
<TooltipProvider>
<div className={classes}>
<Glass className="mx_Dialog_border">
<div className="mx_Dialog">{modal.elem}</div>
</Glass>
{/* We break the rule here as this is a mouse-only interaction */}
{/* oxlint-disable-next-line jsx-a11y/click-events-have-key-events */}
<div
data-testid="dialog-background"
className="mx_Dialog_background"
onClick={this.onBackgroundClick}
/>
</div>
</TooltipProvider>
</LinkedTextContext.Provider>
</I18nContext.Provider>
</SDKContext.Provider>
</StrictMode>