Skip to content

fix(autocomplete): show popover when emptyContent is provided with allowsCustomValue#5951

Merged
wingkwong merged 3 commits into
heroui-inc:canaryfrom
hasegawa-101:fix/autocomplete-empty-content-with-custom-value
Nov 30, 2025
Merged

fix(autocomplete): show popover when emptyContent is provided with allowsCustomValue#5951
wingkwong merged 3 commits into
heroui-inc:canaryfrom
hasegawa-101:fix/autocomplete-empty-content-with-custom-value

Conversation

@hasegawa-101
Copy link
Copy Markdown

@hasegawa-101 hasegawa-101 commented Nov 30, 2025

Closes #5745

📝 Description

This PR fixes an issue where the Autocomplete popover would not appear when allowsCustomValue is true and the input value does not match any items, even if a custom emptyContent was provided.

⛳️ Current behavior (updates)

Currently, when allowsCustomValue is set to true, the hideEmptyContent prop of the Listbox is forced to true. This causes the popover to remain hidden when there are no search results, regardless of whether the user has provided a custom emptyContent

🚀 New behavior

The logic in use-autocomplete.ts has been updated to only default hideEmptyContent to true if allowsCustomValue is true AND no custom emptyContent is provided.

If a user provides a custom emptyContent, the popover will now appear to display that content, even when allowsCustomValue is enabled.

💣 Is this a breaking change (Yes/No):

No

📝 Additional Information

Summary by CodeRabbit

  • New Features

    • Autocomplete now displays the popover with custom empty content when allowsCustomValue is enabled and custom emptyContent is explicitly provided, improving user experience for custom value input.
  • Tests

    • Added test coverage for empty content display behavior with allowsCustomValue, ensuring proper popover visibility across different scenarios.

✏️ Tip: You can customize this high-level summary in your review settings.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Nov 30, 2025

🦋 Changeset detected

Latest commit: 65350f0

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@heroui/autocomplete Patch
@heroui/react Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Copy Markdown

vercel Bot commented Nov 30, 2025

@hasegawa-101 is attempting to deploy a commit to the HeroUI Inc Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Nov 30, 2025

Walkthrough

This PR fixes a bug where the autocomplete popover failed to display when allowCustomValue was true, even with emptyContent provided. The solution modifies the hideEmptyContent logic to conditionally show the popover when explicit emptyContent is supplied, and adds test cases to verify the corrected behavior.

Changes

Cohort / File(s) Summary
Test suite for allowsCustomValue behavior
packages/components/autocomplete/__tests__/autocomplete.test.tsx
Added two test cases within "Autocomplete with allowsCustomValue" describe block to verify that emptyContent displays correctly when the prop is true and emptyContent is provided, and does not display when not provided. Imported waitFor utility from testing library.
Core logic fix
packages/components/autocomplete/src/use-autocomplete.ts
Updated hideEmptyContent assignment from allowsCustomValue to allowsCustomValue && !listboxProps?.emptyContent, ensuring the popover shows when emptyContent is explicitly provided alongside allowsCustomValue.
Release documentation
.changeset/chilly-buckets-leave.md
New changeset file documenting patch release for autocomplete package with feature description of the popover visibility fix.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Single-line logic modification in source file (straightforward conditional adjustment)
  • New tests are verification-focused with clear assertions
  • Changes are narrowly scoped to one component concern
  • No complex interactions or refactoring patterns

Suggested reviewers

  • jrgarciadev
  • wingkwong

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately describes the main fix: showing the popover when emptyContent is provided with allowsCustomValue enabled.
Description check ✅ Passed The description comprehensively covers all template sections with clear explanations of current behavior, new behavior, and confirms no breaking changes.
Linked Issues check ✅ Passed The changes successfully address issue #5745 by fixing the logic to show the popover when custom emptyContent is provided with allowsCustomValue enabled.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the identified issue; the test additions and logic updates in use-autocomplete.ts align with the PR objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 10606c4 and 65350f0.

📒 Files selected for processing (1)
  • .changeset/chilly-buckets-leave.md (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Continuous Release
  • GitHub Check: Build
  • GitHub Check: Tests
  • GitHub Check: ESLint
  • GitHub Check: TypeScript
🔇 Additional comments (1)
.changeset/chilly-buckets-leave.md (1)

1-5: Changeset format and metadata are correct.

The changeset entry properly documents a patch version bump with a clear summary referencing the fixed issue. The format follows standard conventions.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@vercel
Copy link
Copy Markdown

vercel Bot commented Nov 30, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
heroui Ready Ready Preview Comment Nov 30, 2025 3:57pm
heroui-sb Ready Ready Preview Comment Nov 30, 2025 3:57pm

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
packages/components/autocomplete/src/use-autocomplete.ts (1)

298-305: Empty-content behavior now matches the “custom emptyContent with allowsCustomValue” requirement

hideEmptyContent: allowsCustomValue && !listboxProps?.emptyContent does what you want here:

  • allowsCustomValue=false → unchanged: empty content can show.
  • allowsCustomValue=true + custom listboxProps.emptyContenthideEmptyContent defaults to false, so the popover can open and display that custom content.
  • allowsCustomValue=true + no custom emptyContenthideEmptyContent stays true, and the second new test locks in that behavior.

Because mergeProps later lets consumers still override hideEmptyContent explicitly, this is flexible and backwards‑compatible. The only small nit is the naming collision between the destructured listboxProps here and listBoxProps from useComboBox, which can be confusing when scanning the file; consider renaming one of them in a future cleanup for clarity.

If the original issue is meant to also show the default "No results found." message when allowsCustomValue is true (not only custom emptyContent), this implementation intentionally does not do that; confirm that the current behavior is indeed what you want to ship for #5745.

packages/components/autocomplete/stories/autocomplete.stories.tsx (1)

1202-1216: Story accurately exercises the fixed allowsCustomValue + custom emptyContent behavior

This story is a good, minimal repro: allowsCustomValue + defaultItems={[]} + listboxProps.emptyContent directly covers the bug scenario and validates the new behavior visually.

Only minor nit: the child render prop uses (item: any). Since defaultItems is empty here, you could either:

  • Drop the render prop entirely and use static children, or
  • Give Autocomplete an explicit generic / item type instead of any.

Not required for correctness, but it would keep Storybook examples a bit more type‑safe.

packages/components/autocomplete/__tests__/autocomplete.test.tsx (1)

6-7: Tests correctly pin the new allowsCustomValue + emptyContent behavior

The new suite does a good job of:

  • Verifying that custom listboxProps.emptyContent is rendered when allowsCustomValue is true and defaultItems is empty.
  • Explicitly asserting that, without a custom emptyContent, no listbox (and therefore no default empty content) appears when allowsCustomValue is true.

This matches the updated hideEmptyContent logic and guards against regressions.

If you want to harden the second test against potential future async changes in how the popover mounts, you could wrap the negative assertion in a waitFor, e.g.:

await waitFor(() => {
  expect(wrapper.queryByRole("listbox")).toBeNull();
});

Not strictly necessary with the current implementation, but it would make the intent resilient to timing changes.

Also applies to: 1093-1151

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 66ef76e and 10606c4.

📒 Files selected for processing (3)
  • packages/components/autocomplete/__tests__/autocomplete.test.tsx (2 hunks)
  • packages/components/autocomplete/src/use-autocomplete.ts (1 hunks)
  • packages/components/autocomplete/stories/autocomplete.stories.tsx (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Continuous Release
  • GitHub Check: Tests
  • GitHub Check: TypeScript
  • GitHub Check: ESLint
  • GitHub Check: Build

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Nov 30, 2025

Open in StackBlitz

@heroui/accordion

npm i https://pkg.pr.new/@heroui/accordion@5951

@heroui/alert

npm i https://pkg.pr.new/@heroui/alert@5951

@heroui/autocomplete

npm i https://pkg.pr.new/@heroui/autocomplete@5951

@heroui/avatar

npm i https://pkg.pr.new/@heroui/avatar@5951

@heroui/badge

npm i https://pkg.pr.new/@heroui/badge@5951

@heroui/breadcrumbs

npm i https://pkg.pr.new/@heroui/breadcrumbs@5951

@heroui/button

npm i https://pkg.pr.new/@heroui/button@5951

@heroui/calendar

npm i https://pkg.pr.new/@heroui/calendar@5951

@heroui/card

npm i https://pkg.pr.new/@heroui/card@5951

@heroui/checkbox

npm i https://pkg.pr.new/@heroui/checkbox@5951

@heroui/chip

npm i https://pkg.pr.new/@heroui/chip@5951

@heroui/code

npm i https://pkg.pr.new/@heroui/code@5951

@heroui/date-input

npm i https://pkg.pr.new/@heroui/date-input@5951

@heroui/date-picker

npm i https://pkg.pr.new/@heroui/date-picker@5951

@heroui/divider

npm i https://pkg.pr.new/@heroui/divider@5951

@heroui/drawer

npm i https://pkg.pr.new/@heroui/drawer@5951

@heroui/dropdown

npm i https://pkg.pr.new/@heroui/dropdown@5951

@heroui/form

npm i https://pkg.pr.new/@heroui/form@5951

@heroui/image

npm i https://pkg.pr.new/@heroui/image@5951

@heroui/input

npm i https://pkg.pr.new/@heroui/input@5951

@heroui/input-otp

npm i https://pkg.pr.new/@heroui/input-otp@5951

@heroui/kbd

npm i https://pkg.pr.new/@heroui/kbd@5951

@heroui/link

npm i https://pkg.pr.new/@heroui/link@5951

@heroui/listbox

npm i https://pkg.pr.new/@heroui/listbox@5951

@heroui/menu

npm i https://pkg.pr.new/@heroui/menu@5951

@heroui/modal

npm i https://pkg.pr.new/@heroui/modal@5951

@heroui/navbar

npm i https://pkg.pr.new/@heroui/navbar@5951

@heroui/number-input

npm i https://pkg.pr.new/@heroui/number-input@5951

@heroui/pagination

npm i https://pkg.pr.new/@heroui/pagination@5951

@heroui/popover

npm i https://pkg.pr.new/@heroui/popover@5951

@heroui/progress

npm i https://pkg.pr.new/@heroui/progress@5951

@heroui/radio

npm i https://pkg.pr.new/@heroui/radio@5951

@heroui/ripple

npm i https://pkg.pr.new/@heroui/ripple@5951

@heroui/scroll-shadow

npm i https://pkg.pr.new/@heroui/scroll-shadow@5951

@heroui/select

npm i https://pkg.pr.new/@heroui/select@5951

@heroui/skeleton

npm i https://pkg.pr.new/@heroui/skeleton@5951

@heroui/slider

npm i https://pkg.pr.new/@heroui/slider@5951

@heroui/snippet

npm i https://pkg.pr.new/@heroui/snippet@5951

@heroui/spacer

npm i https://pkg.pr.new/@heroui/spacer@5951

@heroui/spinner

npm i https://pkg.pr.new/@heroui/spinner@5951

@heroui/switch

npm i https://pkg.pr.new/@heroui/switch@5951

@heroui/table

npm i https://pkg.pr.new/@heroui/table@5951

@heroui/tabs

npm i https://pkg.pr.new/@heroui/tabs@5951

@heroui/toast

npm i https://pkg.pr.new/@heroui/toast@5951

@heroui/tooltip

npm i https://pkg.pr.new/@heroui/tooltip@5951

@heroui/user

npm i https://pkg.pr.new/@heroui/user@5951

@heroui/react

npm i https://pkg.pr.new/@heroui/react@5951

@heroui/system

npm i https://pkg.pr.new/@heroui/system@5951

@heroui/system-rsc

npm i https://pkg.pr.new/@heroui/system-rsc@5951

@heroui/theme

npm i https://pkg.pr.new/@heroui/theme@5951

@heroui/use-aria-accordion

npm i https://pkg.pr.new/@heroui/use-aria-accordion@5951

@heroui/use-aria-accordion-item

npm i https://pkg.pr.new/@heroui/use-aria-accordion-item@5951

@heroui/use-aria-button

npm i https://pkg.pr.new/@heroui/use-aria-button@5951

@heroui/use-aria-link

npm i https://pkg.pr.new/@heroui/use-aria-link@5951

@heroui/use-aria-modal-overlay

npm i https://pkg.pr.new/@heroui/use-aria-modal-overlay@5951

@heroui/use-aria-multiselect

npm i https://pkg.pr.new/@heroui/use-aria-multiselect@5951

@heroui/use-aria-overlay

npm i https://pkg.pr.new/@heroui/use-aria-overlay@5951

@heroui/use-callback-ref

npm i https://pkg.pr.new/@heroui/use-callback-ref@5951

@heroui/use-clipboard

npm i https://pkg.pr.new/@heroui/use-clipboard@5951

@heroui/use-data-scroll-overflow

npm i https://pkg.pr.new/@heroui/use-data-scroll-overflow@5951

@heroui/use-disclosure

npm i https://pkg.pr.new/@heroui/use-disclosure@5951

@heroui/use-draggable

npm i https://pkg.pr.new/@heroui/use-draggable@5951

@heroui/use-form-reset

npm i https://pkg.pr.new/@heroui/use-form-reset@5951

@heroui/use-image

npm i https://pkg.pr.new/@heroui/use-image@5951

@heroui/use-infinite-scroll

npm i https://pkg.pr.new/@heroui/use-infinite-scroll@5951

@heroui/use-intersection-observer

npm i https://pkg.pr.new/@heroui/use-intersection-observer@5951

@heroui/use-is-mobile

npm i https://pkg.pr.new/@heroui/use-is-mobile@5951

@heroui/use-is-mounted

npm i https://pkg.pr.new/@heroui/use-is-mounted@5951

@heroui/use-measure

npm i https://pkg.pr.new/@heroui/use-measure@5951

@heroui/use-pagination

npm i https://pkg.pr.new/@heroui/use-pagination@5951

@heroui/use-real-shape

npm i https://pkg.pr.new/@heroui/use-real-shape@5951

@heroui/use-ref-state

npm i https://pkg.pr.new/@heroui/use-ref-state@5951

@heroui/use-resize

npm i https://pkg.pr.new/@heroui/use-resize@5951

@heroui/use-safe-layout-effect

npm i https://pkg.pr.new/@heroui/use-safe-layout-effect@5951

@heroui/use-scroll-position

npm i https://pkg.pr.new/@heroui/use-scroll-position@5951

@heroui/use-ssr

npm i https://pkg.pr.new/@heroui/use-ssr@5951

@heroui/use-theme

npm i https://pkg.pr.new/@heroui/use-theme@5951

@heroui/use-update-effect

npm i https://pkg.pr.new/@heroui/use-update-effect@5951

@heroui/use-viewport-size

npm i https://pkg.pr.new/@heroui/use-viewport-size@5951

@heroui/aria-utils

npm i https://pkg.pr.new/@heroui/aria-utils@5951

@heroui/dom-animation

npm i https://pkg.pr.new/@heroui/dom-animation@5951

@heroui/framer-utils

npm i https://pkg.pr.new/@heroui/framer-utils@5951

@heroui/react-rsc-utils

npm i https://pkg.pr.new/@heroui/react-rsc-utils@5951

@heroui/react-utils

npm i https://pkg.pr.new/@heroui/react-utils@5951

@heroui/shared-icons

npm i https://pkg.pr.new/@heroui/shared-icons@5951

@heroui/shared-utils

npm i https://pkg.pr.new/@heroui/shared-utils@5951

@heroui/stories-utils

npm i https://pkg.pr.new/@heroui/stories-utils@5951

@heroui/test-utils

npm i https://pkg.pr.new/@heroui/test-utils@5951

commit: 65350f0

@wingkwong wingkwong self-assigned this Nov 30, 2025
@wingkwong wingkwong added this to the v2.8.6 milestone Nov 30, 2025
@wingkwong wingkwong merged commit b4cfb40 into heroui-inc:canary Nov 30, 2025
10 checks passed
AnYiEE added a commit to AnYiEE/touhou-mystia-izakaya-assistant that referenced this pull request Dec 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] - Autocomplete doesn't show up the popover when no results or empty value when allowCustomValue is true

2 participants