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(