diff --git a/.changeset/rotten-jobs-pull.md b/.changeset/rotten-jobs-pull.md new file mode 100644 index 0000000000..c467de7d62 --- /dev/null +++ b/.changeset/rotten-jobs-pull.md @@ -0,0 +1,6 @@ +--- +"@nextui-org/use-aria-multiselect": patch +"@nextui-org/select": patch +--- + +add hideEmptyContent API to select diff --git a/apps/docs/content/docs/components/select.mdx b/apps/docs/content/docs/components/select.mdx index 570cfa86ca..7d05d3190d 100644 --- a/apps/docs/content/docs/components/select.mdx +++ b/apps/docs/content/docs/components/select.mdx @@ -485,7 +485,7 @@ the popover and listbox components. }, { attribute: "endContent", - type: "ReactNode", + type: "ReactNode", description: "Element to be rendered in the right side of the select.", default: "-" }, @@ -515,7 +515,7 @@ the popover and listbox components. }, { attribute: "itemHeight", - type: "number", + type: "number", description: "The fixed height of each item in pixels. Required when using virtualization.", default: "32" }, @@ -603,6 +603,12 @@ the popover and listbox components. description: "Whether the select should disable the rotation of the selector icon.", default: "false" }, + { + attribute: "hideEmptyContent", + type: "boolean", + description: "Whether the listbox will be prevented from opening when there are no items.", + default: "false" + }, { attribute: "popoverProps", type: "PopoverProps", diff --git a/packages/components/select/__tests__/select.test.tsx b/packages/components/select/__tests__/select.test.tsx index 8f90aa7678..470cd130ef 100644 --- a/packages/components/select/__tests__/select.test.tsx +++ b/packages/components/select/__tests__/select.test.tsx @@ -828,6 +828,57 @@ describe("Select", () => { "Invalid value", ); }); + + it("should not open dropdown when hideEmptyContent is true", async () => { + const wrapper = render( + , + ); + + const select = wrapper.getByTestId("hide-empty-content-true-test"); + + // open the select dropdown + await user.click(select); + + // assert that the select is not open + expect(select).not.toHaveAttribute("aria-expanded", "true"); + // assert that the listbox is not rendered + expect(wrapper.queryByRole("listbox")).not.toBeInTheDocument(); + }); + + it("should open dropdown when hideEmptyContent is false", async () => { + const wrapper = render( + , + ); + + const select = wrapper.getByTestId("hide-empty-content-false-test"); + + // open the select dropdown + await user.click(select); + + // assert that the select is open + expect(select).toHaveAttribute("aria-expanded", "true"); + + const listbox = wrapper.getByRole("listbox"); + + // assert that the listbox is rendered + expect(listbox).toBeInTheDocument(); + // assert that the listbox items are not rendered + expect(wrapper.queryByRole("option")).not.toBeInTheDocument(); + }); }); describe("Select virtualization tests", () => { diff --git a/packages/components/select/src/use-select.ts b/packages/components/select/src/use-select.ts index 9fd67a73c5..6cc12c628e 100644 --- a/packages/components/select/src/use-select.ts +++ b/packages/components/select/src/use-select.ts @@ -166,6 +166,11 @@ export type UseSelectProps = Omit< * @default undefined */ isVirtualized?: boolean; + /** + * Whether the listbox will be prevented from opening when there are no items. + * @default false + */ + hideEmptyContent?: boolean; }; export function useSelect(originalProps: UseSelectProps) { @@ -209,6 +214,7 @@ export function useSelect(originalProps: UseSelectProps) { onClose, className, classNames, + hideEmptyContent = false, ...otherProps } = props; @@ -263,6 +269,7 @@ export function useSelect(originalProps: UseSelectProps) { isDisabled: originalProps.isDisabled, isInvalid: originalProps.isInvalid, defaultOpen, + hideEmptyContent, onOpenChange: (open) => { onOpenChange?.(open); if (!open) { diff --git a/packages/components/select/stories/select.stories.tsx b/packages/components/select/stories/select.stories.tsx index f768f58e49..70920b4247 100644 --- a/packages/components/select/stories/select.stories.tsx +++ b/packages/components/select/stories/select.stories.tsx @@ -411,6 +411,31 @@ const StartContentTemplate = ({color, variant, ...args}: SelectProps) => ( ); +const EmptyTemplate = ({color, variant, ...args}: SelectProps) => ( +
+ + +
+); + const CustomItemsTemplate = ({color, variant, ...args}: SelectProps) => (