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.
This commit is contained in:
@@ -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(<ContextMenuTrigger style={rowStyle} />);
|
||||||
|
|
||||||
|
expect(captured.style).toBe(rowStyle);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -178,7 +178,7 @@ export function ContextMenuTrigger({
|
|||||||
[onContextMenu, openAtEvent],
|
[onContextMenu, openAtEvent],
|
||||||
);
|
);
|
||||||
|
|
||||||
const pressableStyle = useCallback(
|
const resolveDynamicStyle = useCallback(
|
||||||
({ pressed, hovered = false }: PressableStateCallbackType & { hovered?: boolean }) => {
|
({ pressed, hovered = false }: PressableStateCallbackType & { hovered?: boolean }) => {
|
||||||
if (typeof style === "function") {
|
if (typeof style === "function") {
|
||||||
return style({ pressed, hovered, open: ctx.open });
|
return style({ pressed, hovered, open: ctx.open });
|
||||||
@@ -198,7 +198,7 @@ export function ContextMenuTrigger({
|
|||||||
onLongPress={handleLongPress}
|
onLongPress={handleLongPress}
|
||||||
// @ts-ignore - onContextMenu is web-only and not in RN types.
|
// @ts-ignore - onContextMenu is web-only and not in RN types.
|
||||||
onContextMenu={handleContextMenu}
|
onContextMenu={handleContextMenu}
|
||||||
style={pressableStyle}
|
style={typeof style === "function" ? resolveDynamicStyle : style}
|
||||||
highlightStyle={highlightStyle}
|
highlightStyle={highlightStyle}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
Reference in New Issue
Block a user