Move EventTile to shared components - #3a (#34458)

* Refactor Mjolnir body to use render-only view model actions

* Extracted isMjolnirBodyAllowed from MessageEvent

* Converted the new test file to vitest
This commit is contained in:
rbondesson
2026-07-30 14:50:57 +00:00
committed by GitHub
parent d4d4794f7e
commit 82b313828a
8 changed files with 131 additions and 106 deletions
@@ -18,8 +18,8 @@ type MjolnirBodyViewProps = MjolnirBodyViewSnapshot &
className?: string;
};
const MjolnirBodyViewWrapperImpl = ({ onAllowClick, className, ...snapshot }: MjolnirBodyViewProps): JSX.Element => {
const vm = useMockedViewModel(snapshot, { onAllowClick });
const MjolnirBodyViewWrapperImpl = ({ onAllow, className, ...snapshot }: MjolnirBodyViewProps): JSX.Element => {
const vm = useMockedViewModel(snapshot, { onAllow });
return <MjolnirBodyView vm={vm} className={className} />;
};
@@ -31,7 +31,7 @@ const meta = {
component: MjolnirBodyViewWrapper,
tags: ["autodocs"],
args: {
onAllowClick: fn(),
onAllow: fn(),
className: "",
},
} satisfies Meta<typeof MjolnirBodyViewWrapper>;
@@ -25,7 +25,7 @@ const { Default } = composeStories(stories);
class TestMjolnirBodyViewModel extends MockViewModel<MjolnirBodyViewSnapshot> implements MjolnirBodyViewActions {
public constructor(
snapshot: MjolnirBodyViewSnapshot,
public onAllowClick: MjolnirBodyViewActions["onAllowClick"],
public onAllow: MjolnirBodyViewActions["onAllow"],
) {
super(snapshot);
}
@@ -42,14 +42,15 @@ describe("MjolnirBodyView", () => {
it("invokes the allow action", async () => {
const user = userEvent.setup();
const onAllowClick = vi.fn();
const vm = new TestMjolnirBodyViewModel({}, onAllowClick) as MjolnirBodyViewModel;
const onAllow = vi.fn();
const vm = new TestMjolnirBodyViewModel({}, onAllow) as MjolnirBodyViewModel;
render(<MjolnirBodyView vm={vm} />);
await user.click(screen.getByRole("button", { name: "Show anyways." }));
expect(onAllowClick).toHaveBeenCalledTimes(1);
expect(onAllow).toHaveBeenCalledTimes(1);
expect(onAllow).toHaveBeenCalledWith();
});
it("applies a custom className to the root element", () => {
@@ -6,7 +6,7 @@
*/
import classNames from "classnames";
import React, { type JSX, type MouseEventHandler, type Ref } from "react";
import React, { type JSX, type Ref } from "react";
import { type ViewModel, useViewModel } from "../../../../../core/viewmodel";
import { useI18n } from "../../../../../core/i18n/i18nContext";
@@ -18,7 +18,7 @@ export interface MjolnirBodyViewActions {
/**
* Invoked when the user chooses to show the hidden message.
*/
onAllowClick: MouseEventHandler<HTMLButtonElement>;
onAllow: () => void;
}
export type MjolnirBodyViewModel = ViewModel<MjolnirBodyViewSnapshot, MjolnirBodyViewActions>;
@@ -53,7 +53,15 @@ export function MjolnirBodyView({ vm, className, ref }: Readonly<MjolnirBodyView
{},
{
a: (sub) => (
<button type="button" className={styles.allowButton} onClick={vm.onAllowClick}>
<button
type="button"
className={styles.allowButton}
onClick={(event) => {
event.preventDefault();
event.stopPropagation();
vm.onAllow();
}}
>
{sub}
</button>
),