diff --git a/packages/views/issues/components/pickers/assignee-picker.tsx b/packages/views/issues/components/pickers/assignee-picker.tsx index 006306127..0e89bfe49 100644 --- a/packages/views/issues/components/pickers/assignee-picker.tsx +++ b/packages/views/issues/components/pickers/assignee-picker.tsx @@ -66,10 +66,12 @@ interface AssigneePickerProps { * itself), so trigger-less callers stay eager. */ export function AssigneePicker(props: AssigneePickerProps) { + const hasDeferredTriggerContent = + props.trigger !== undefined || props.triggerRender?.props.children != null; const canDefer = props.open === undefined && props.onOpenChange === undefined && - (props.trigger !== undefined || props.triggerRender !== undefined); + hasDeferredTriggerContent; if (!canDefer) { return ; } diff --git a/packages/views/issues/components/pickers/deferred-trigger.test.tsx b/packages/views/issues/components/pickers/deferred-trigger.test.tsx new file mode 100644 index 000000000..49002cb30 --- /dev/null +++ b/packages/views/issues/components/pickers/deferred-trigger.test.tsx @@ -0,0 +1,55 @@ +// @vitest-environment jsdom + +import { cleanup, screen } from "@testing-library/react"; +import { afterEach, describe, expect, it, vi } from "vitest"; +import { renderWithI18n } from "../../../test/i18n"; +import { PillButton } from "../../../common/pill-button"; +import { AssigneePicker } from "./assignee-picker"; +import { PriorityPicker } from "./priority-picker"; + +vi.mock("@tanstack/react-query", async (importOriginal) => ({ + ...(await importOriginal()), + useQuery: () => ({ data: [] }), +})); + +vi.mock("@multica/core/auth", () => ({ + useAuthStore: (selector: (state: { user: null }) => unknown) => + selector({ user: null }), +})); + +vi.mock("@multica/core/hooks", () => ({ + useWorkspaceId: () => "workspace-1", +})); + +vi.mock("@multica/core/workspace/hooks", () => ({ + useActorName: () => ({ getActorName: () => "Unknown" }), +})); + +afterEach(cleanup); + +describe("deferred picker triggers", () => { + it("renders generated content when triggerRender only supplies an empty shell", () => { + renderWithI18n( + <> + {}} + triggerRender={} + /> + {}} + triggerRender={} + /> + , + ); + + expect( + screen.getByRole("button", { name: "No priority" }), + ).toBeInTheDocument(); + expect( + screen.getByRole("button", { name: "Unassigned" }), + ).toBeInTheDocument(); + }); +}); diff --git a/packages/views/issues/components/pickers/priority-picker.tsx b/packages/views/issues/components/pickers/priority-picker.tsx index d7f968e6f..ea7217260 100644 --- a/packages/views/issues/components/pickers/priority-picker.tsx +++ b/packages/views/issues/components/pickers/priority-picker.tsx @@ -33,11 +33,13 @@ interface PriorityPickerProps { * on first interaction. See `DeferredPopup` for why. */ export function PriorityPicker(props: PriorityPickerProps) { + const hasDeferredTriggerContent = + props.trigger !== undefined || props.triggerRender?.props.children != null; const canDefer = props.open === undefined && props.onOpenChange === undefined && !props.defaultOpen && - (props.trigger !== undefined || props.triggerRender !== undefined); + hasDeferredTriggerContent; if (!canDefer) { return ; }