mirror of
https://github.com/vector-im/element-call.git
synced 2026-10-13 23:35:51 +00:00
[ElementCallComponent] Use compound-web's PortalRoot in EC.
This commit is contained in:
@@ -11,6 +11,7 @@ import { type ReactNode, useState } from "react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
|
||||
import { Modal } from "./Modal";
|
||||
import { RootElementProvider } from "./RootElementContext";
|
||||
|
||||
const originalMatchMedia = window.matchMedia;
|
||||
afterEach(() => {
|
||||
@@ -70,3 +71,39 @@ test("the modal renders as a drawer in mobile viewports", () => {
|
||||
);
|
||||
expect(queryByRole("dialog")).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("the modal can be closed by clicking the backdrop, in another window too", async () => {
|
||||
// The drawer test above leaves a touchscreen matchMedia behind; this is
|
||||
// about the desktop dialog
|
||||
window.matchMedia = (): MediaQueryList =>
|
||||
({
|
||||
matches: false,
|
||||
addEventListener: (): void => {},
|
||||
removeEventListener: (): void => {},
|
||||
}) as unknown as MediaQueryList;
|
||||
// A dialog moved into another window, as a host does for a Document
|
||||
// Picture-in-Picture window: its nodes are not `Node`s of this window
|
||||
const frame = document.createElement("iframe");
|
||||
document.body.appendChild(frame);
|
||||
const otherBody = frame.contentDocument!.body;
|
||||
|
||||
function ModalFn(): ReactNode {
|
||||
const [isOpen, setOpen] = useState(true);
|
||||
return (
|
||||
<RootElementProvider value={otherBody}>
|
||||
<Modal title="My modal" open={isOpen} onDismiss={() => setOpen(false)}>
|
||||
<p>This is the content.</p>
|
||||
</Modal>
|
||||
</RootElementProvider>
|
||||
);
|
||||
}
|
||||
render(<ModalFn />);
|
||||
const dialog = otherBody.querySelector('[role="dialog"]');
|
||||
expect(dialog).not.toBeNull();
|
||||
const backdrop = dialog!.previousElementSibling as HTMLElement;
|
||||
|
||||
const user = userEvent.setup({ document: frame.contentDocument! });
|
||||
await user.click(backdrop);
|
||||
expect(otherBody.querySelector('[role="dialog"]')).toBeNull();
|
||||
frame.remove();
|
||||
});
|
||||
|
||||
@@ -160,6 +160,12 @@ export const Modal: FC<Props> = ({
|
||||
<DialogPortal container={rootElement}>
|
||||
<DialogOverlay
|
||||
className={classNames(overlayStyles.bg, overlayStyles.animate)}
|
||||
// Radix dismisses on a pointer down outside the dialog, but only
|
||||
// for event targets that are a `Node` of the window it was loaded
|
||||
// in. A host can move the dialog into another window (a Document
|
||||
// Picture-in-Picture window), whose nodes fail that check, so the
|
||||
// backdrop closes the dialog itself.
|
||||
onClick={() => onDismiss?.()}
|
||||
/>
|
||||
<DialogContent
|
||||
asChild
|
||||
|
||||
@@ -15,7 +15,7 @@ exports[`AppBar > renders 1`] = `
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="_indicator-icon_147l5_17"
|
||||
class="_indicator-icon_j097f_17"
|
||||
style="--cpd-icon-button-size: 100%;"
|
||||
>
|
||||
<svg
|
||||
@@ -58,7 +58,7 @@ exports[`AppBar > renders with title and subtitle 1`] = `
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="_indicator-icon_147l5_17"
|
||||
class="_indicator-icon_j097f_17"
|
||||
style="--cpd-icon-button-size: 100%;"
|
||||
>
|
||||
<svg
|
||||
|
||||
@@ -181,7 +181,7 @@ exports[`InCallView > rendering > renders 1`] = `
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="_indicator-icon_147l5_17"
|
||||
class="_indicator-icon_j097f_17"
|
||||
style="--cpd-icon-button-size: 100%;"
|
||||
>
|
||||
<svg
|
||||
|
||||
@@ -15,7 +15,7 @@ exports[`LobbyView > renders with AppBar android 1`] = `
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="_indicator-icon_147l5_17"
|
||||
class="_indicator-icon_j097f_17"
|
||||
style="--cpd-icon-button-size: 100%;"
|
||||
>
|
||||
<svg
|
||||
@@ -111,7 +111,7 @@ exports[`LobbyView > renders with AppBar android 1`] = `
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="_indicator-icon_147l5_17"
|
||||
class="_indicator-icon_j097f_17"
|
||||
style="--cpd-icon-button-size: 100%;"
|
||||
>
|
||||
<svg
|
||||
@@ -247,7 +247,7 @@ exports[`LobbyView > renders with AppBar ios 1`] = `
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="_indicator-icon_147l5_17"
|
||||
class="_indicator-icon_j097f_17"
|
||||
style="--cpd-icon-button-size: 100%;"
|
||||
>
|
||||
<svg
|
||||
@@ -343,7 +343,7 @@ exports[`LobbyView > renders with AppBar ios 1`] = `
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="_indicator-icon_147l5_17"
|
||||
class="_indicator-icon_j097f_17"
|
||||
style="--cpd-icon-button-size: 100%;"
|
||||
>
|
||||
<svg
|
||||
@@ -621,7 +621,7 @@ exports[`LobbyView > renders with header and participant count 1`] = `
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="_indicator-icon_147l5_17"
|
||||
class="_indicator-icon_j097f_17"
|
||||
style="--cpd-icon-button-size: 100%;"
|
||||
>
|
||||
<svg
|
||||
|
||||
Reference in New Issue
Block a user