Skip to content

Conversation

@FabienMotte
Copy link
Contributor

@FabienMotte FabienMotte commented Feb 10, 2026

Summary

This PR adds a responsive detached mode to the Autocomplete widget for mobile devices. When a configurable media query matches (default: max-width: 680px), the inline search input is replaced with a search button that opens a full-screen overlay with the search form and results panel.

  • New detachedMediaQuery option to control when detached mode activates (set to "" to disable)
  • New translations option for detached mode UI text (cancel button, search button title, clear button title)
  • Two layout variants: full-screen on phones, centered modal on tablets (controlled via CSS variables)
  • Body scroll is locked while the overlay is open, panel stays open in detached mode
  • Smooth transitions when resizing between detached and non-detached modes
  • New CSS variables for overlay color, modal dimensions, and media query breakpoints
  • New shared UI components: AutocompleteDetachedSearchButton, AutocompleteDetachedOverlay, AutocompleteDetachedContainer, AutocompleteDetachedFormContainer
  • Refactored AutocompleteSearch (React) to accept props directly instead of using useSearchBox internally
  • Updated bundle size limits, z-index layering (Chat 9998, Autocomplete 10000)
  • Added common widget tests for detached mode
  • Updated react/query-suggestions example with mobile-responsive layout

Result

Verified with the react/query-suggestions example (yarn start in examples/react/query-suggestions):

  • Desktop (> 680px): Standard inline autocomplete with search input and dropdown panel.
  • Mobile (≤ 680px): Search input is replaced by a search button. Tapping it opens a full-screen overlay with the search form, cancel button, and results panel. Tapping the overlay backdrop or pressing Cancel closes it. Submitting a query (Enter) closes the overlay and applies the search.
  • Tablet / modal variant (≤ 1024px, ≥ 680px): Overlay renders as a centered modal dialog instead of full-screen.
  • Resize transitions: Shrinking the viewport while the panel is open seamlessly transitions into the detached overlay. Expanding back closes the overlay and returns to inline mode.
  • Scroll lock: Body scroll is prevented while the overlay is open and restored to the correct position on close.
  • Clear button: The detached search button shows the current query and a clear button to reset it.
  • detachedMediaQuery="": Completely disables detached mode.

All common widget tests pass for both instantsearch.js and react-instantsearch.

image image

@codesandbox-ci
Copy link

codesandbox-ci bot commented Feb 10, 2026

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 3280367:

Sandbox Source
example-instantsearch-getting-started Configuration
example-react-instantsearch-getting-started Configuration
example-react-instantsearch-next-app-dir-example Configuration
example-react-instantsearch-next-routing-example Configuration
example-vue-instantsearch-getting-started Configuration

@FabienMotte FabienMotte force-pushed the feat/autocomplete-mobile-support branch from 28362c5 to daac09d Compare February 10, 2026 11:17
@FabienMotte FabienMotte force-pushed the feat/autocomplete-mobile-support branch from 377d239 to 8f597ab Compare February 10, 2026 12:29
@FabienMotte FabienMotte marked this pull request as ready for review February 10, 2026 12:41
@FabienMotte FabienMotte requested review from a team, aymeric-giraudet and shaejaz and removed request for a team February 10, 2026 12:42
@FabienMotte FabienMotte requested a review from Haroenv February 11, 2026 07:23
Copy link
Contributor

@Haroenv Haroenv left a comment

Choose a reason for hiding this comment

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

looks great, thanks!

const [isModalOpen, setIsModalOpen] = useState(false);
const [isModalDetached, setIsModalDetached] = useState(false);

useEffect(() => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could these useEffect's be done in the ui-components? We already have the hook being passed to them (via the prop getter function I believe)

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.

3 participants