From 851dcb8d4a9a8cd19faa81b9c8a8cab4e2496460 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Mon, 17 Aug 2026 21:05:04 +0200 Subject: [PATCH] fix(app): preserve static context-menu trigger styles Passing a static style through a dynamic callback prevented the native press highlight from inheriting the trigger's corners. --- .../src/components/ui/context-menu.test.tsx | 53 +++++++++++++++++++ .../app/src/components/ui/context-menu.tsx | 4 +- 2 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 packages/app/src/components/ui/context-menu.test.tsx diff --git a/packages/app/src/components/ui/context-menu.test.tsx b/packages/app/src/components/ui/context-menu.test.tsx new file mode 100644 index 000000000..d1b821602 --- /dev/null +++ b/packages/app/src/components/ui/context-menu.test.tsx @@ -0,0 +1,53 @@ +import React from "react"; +import { renderToStaticMarkup } from "react-dom/server"; +import { afterEach, describe, expect, it, vi } from "vitest"; +import { ContextMenuTrigger } from "./context-menu"; + +const captured = vi.hoisted(() => ({ + style: undefined as unknown, +})); + +vi.mock("react-native", () => ({ + Platform: { OS: "web" }, + StatusBar: {}, +})); + +vi.mock("@/constants/platform", () => ({ + isNative: false, + isWeb: true, +})); + +vi.mock("@/components/ui/menu", () => ({ + MenuHint: () => null, + MenuItem: () => null, + MenuLabel: () => null, + MenuRoot: () => null, + MenuSeparator: () => null, + MenuSurface: () => null, + useMenuContext: () => ({ + open: false, + setAnchorRect: vi.fn(), + setOpen: vi.fn(), + triggerRef: undefined, + }), +})); + +vi.mock("@/components/ui/press-highlight", () => ({ + PressHighlight: (props: { style?: unknown }) => { + captured.style = props.style; + return null; + }, +})); + +afterEach(() => vi.unstubAllGlobals()); + +describe("ContextMenuTrigger", () => { + it("preserves a static trigger style so the native press highlight can inherit its corners", () => { + vi.stubGlobal("React", React); + const rowStyle = [{ borderRadius: 8 }, { backgroundColor: "#111" }]; + + renderToStaticMarkup(); + + expect(captured.style).toBe(rowStyle); + }); +}); diff --git a/packages/app/src/components/ui/context-menu.tsx b/packages/app/src/components/ui/context-menu.tsx index 8b117c801..5a0dbe30a 100644 --- a/packages/app/src/components/ui/context-menu.tsx +++ b/packages/app/src/components/ui/context-menu.tsx @@ -178,7 +178,7 @@ export function ContextMenuTrigger({ [onContextMenu, openAtEvent], ); - const pressableStyle = useCallback( + const resolveDynamicStyle = useCallback( ({ pressed, hovered = false }: PressableStateCallbackType & { hovered?: boolean }) => { if (typeof style === "function") { return style({ pressed, hovered, open: ctx.open }); @@ -198,7 +198,7 @@ export function ContextMenuTrigger({ onLongPress={handleLongPress} // @ts-ignore - onContextMenu is web-only and not in RN types. onContextMenu={handleContextMenu} - style={pressableStyle} + style={typeof style === "function" ? resolveDynamicStyle : style} highlightStyle={highlightStyle} > {children}