From 7cc1bd78a30045f2e4370df5738ec3e4ae3933f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D5=A1=D3=84=D5=A1?= Date: Sat, 6 Jul 2024 15:24:17 +0800 Subject: [PATCH] fix(select): close select by pressing selector button (#3374) * feat(select): add test * fix(select): use domRef in ariaShouldCloseOnInteractOutside * feat(changeset): add changeset * fix(select): rewrite "should unset form value" test --- .changeset/curvy-students-judge.md | 5 ++ .../select/__tests__/select.test.tsx | 59 +++++++++++++++---- packages/components/select/src/use-select.ts | 4 +- 3 files changed, 53 insertions(+), 15 deletions(-) create mode 100644 .changeset/curvy-students-judge.md diff --git a/.changeset/curvy-students-judge.md b/.changeset/curvy-students-judge.md new file mode 100644 index 0000000000..124ab0f9b0 --- /dev/null +++ b/.changeset/curvy-students-judge.md @@ -0,0 +1,5 @@ +--- +"@nextui-org/select": patch +--- + +fixed select closing issue with selector button (#3276) diff --git a/packages/components/select/__tests__/select.test.tsx b/packages/components/select/__tests__/select.test.tsx index 280ae91f74..2c64374628 100644 --- a/packages/components/select/__tests__/select.test.tsx +++ b/packages/components/select/__tests__/select.test.tsx @@ -564,7 +564,12 @@ describe("Select", () => { console.log(JSON.stringify(Object.fromEntries(formData))); }} > - foo bar @@ -574,6 +579,14 @@ describe("Select", () => { , ); + const submitButton = wrapper.getByTestId("submit-button"); + + await act(async () => { + await user.click(submitButton); + }); + + expect(logSpy).toHaveBeenCalledWith(JSON.stringify({select: "foo"})); + const select = wrapper.getByTestId("select"); expect(select).not.toBeNull(); @@ -582,39 +595,59 @@ describe("Select", () => { await user.click(select); }); - let listbox = wrapper.getByRole("listbox"); + const listbox = wrapper.getByRole("listbox"); expect(listbox).toBeTruthy(); - let listboxItems = wrapper.getAllByRole("option"); + const listboxItems = wrapper.getAllByRole("option"); expect(listboxItems.length).toBe(2); await act(async () => { - await user.click(listboxItems[1]); + await user.click(listboxItems[0]); }); - let submitButton = wrapper.getByTestId("submit-button"); - await act(async () => { await user.click(submitButton); }); - expect(logSpy).toHaveBeenCalledWith(JSON.stringify({select: "bar"})); + expect(logSpy).toHaveBeenCalledWith(JSON.stringify({select: ""})); + }); - await act(async () => { - await user.click(select); - }); + it("should close listbox by clicking selector button again", async () => { + const wrapper = render( + , + ); + + const select = wrapper.getByTestId("select"); + + expect(select).not.toBeNull(); + // open the select listbox by clicking selector button await act(async () => { - await user.click(listboxItems[1]); + await userEvent.click(select); }); + // assert that the select listbox is open + expect(select).toHaveAttribute("aria-expanded", "true"); + + // open the select listbox by clicking selector button await act(async () => { - await user.click(submitButton); + await userEvent.click(select); }); - expect(logSpy).toHaveBeenCalledWith(JSON.stringify({select: ""})); + // assert that the select listbox is closed + expect(select).toHaveAttribute("aria-expanded", "false"); }); }); diff --git a/packages/components/select/src/use-select.ts b/packages/components/select/src/use-select.ts index fb3b730b6e..08ea8ae885 100644 --- a/packages/components/select/src/use-select.ts +++ b/packages/components/select/src/use-select.ts @@ -524,7 +524,7 @@ export function useSelect(originalProps: UseSelectProps) { : slotsProps.popoverProps?.offset, shouldCloseOnInteractOutside: popoverProps?.shouldCloseOnInteractOutside ? popoverProps.shouldCloseOnInteractOutside - : (element: Element) => ariaShouldCloseOnInteractOutside(element, triggerRef, state), + : (element: Element) => ariaShouldCloseOnInteractOutside(element, domRef, state), } as PopoverProps; }, [ @@ -544,7 +544,7 @@ export function useSelect(originalProps: UseSelectProps) { "data-open": dataAttr(state.isOpen), className: slots.selectorIcon({class: classNames?.selectorIcon}), }), - [slots, classNames?.selectorIcon, state?.isOpen], + [slots, classNames?.selectorIcon, state.isOpen], ); const getInnerWrapperProps: PropGetter = useCallback(