feat(PhoneNumberInput): add country + dial-code search#3313
feat(PhoneNumberInput): add country + dial-code search#3313rzp-slash[bot] wants to merge 8 commits intomasterfrom
Conversation
- Add a search TextInput inside the country selector dropdown (desktop)
and BottomSheetHeader (mobile) so users can filter the 240+ country
list by name, ISO code, or dial code (e.g. "india", "IN", "91", "+91")
- Filtering is memoized and case-insensitive; the "+" prefix is stripped
before matching dial codes
- Reset search query automatically when the dropdown/BottomSheet closes
- Disable ActionList virtualization on mobile (isVirtualized={!isMobile})
to fix the BottomSheet scroll conflict that was causing rendering
artefacts; virtualization remains enabled on desktop
- Register DesktopSearchHeader via setHasAutoCompleteInHeader so the
Dropdown does not preventDefault on mouse-down in the header, allowing
the search TextInput to receive focus correctly
- Add CountrySelector.web.test.tsx with unit tests covering filter by
name, ISO code, dial code (±), empty results, reset-on-close, and
country selection callback
- Add Storybook interaction stories: SearchByCountryName,
SearchByDialCode, SearchResetOnClose
Fixes: country selector lag reported in Slack thread (isVirtualized was
always true, causing re-renders of 240+ items inside BottomSheet scroll).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
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 dccdc86:
|
… input - Replace DropdownHeader + setHasAutoCompleteInHeader with a plain BaseBox wrapper. The hasAutoCompleteInHeader flag routes ActionList through Blade's AutoComplete filter path (filteredValues), which is always empty for a plain TextInput, hiding all countries. - Stop click/mousedown propagation on the search box wrapper to prevent the event from bubbling through the React portal tree to BaseInput's onClick handler (inputRef.current?.focus()), which was stealing focus back to the phone number input on every click. - Auto-focus the search input via a CountrySelector useEffect that runs after DropdownOverlay's effect (React runs child effects first), so it wins the focus race against DropdownOverlay's triggererRef.focus() call. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
✅ PR title follows Conventional Commits specification. |
…us for mobile & desktop - Extract search TextInput + BaseBox wrapper into a typed SearchInput component using React.forwardRef - Define SearchInputProps type (value, onChange, onClearButtonClick) for explicit typing - Remove redundant onMouseDown stopPropagation (only onClick steals focus via BaseInput) - Remove !isMobile guard from auto-focus useEffect so search is focused on both mobile (BottomSheet) and desktop (DropdownOverlay) - Rename inner onChange destructured value to inputValue to avoid shadowing the prop Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… search
- Fix role='option' → role='menuitem' in unit tests and storybook play
functions; InputDropdownButton triggers a menu pattern so ActionListItem
renders with role="menuitem" (confirmed tests were never passing at source)
- Remove !isMobile guard from auto-focus useEffect so search input is
focused on both desktop and bottom-sheet (mobile)
- Add auto-focus test case to CountrySelector.web.test.tsx
- Add CountrySearch story with description of name/ISO/dial-code filtering
- Remove isVirtualized={!isMobile} (revert virtualisation disable on mobile)
- Minor formatting clean-ups in test stories (JSX inline returns)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
🛡️ Coverage ReportSummaryFull Coverage Details |
Fixes 4 bugs reported by Anurag in the CountrySelector search PR: **Bug 1 — Arrow navigation broken after adding search** Forward ArrowUp / ArrowDown / Enter from the search TextInput to the Dropdown's onTriggerKeydown so the user can navigate and select a country without ever leaving the search box. **Bug 2 — TypeAhead causes state desync (Malaysia text + India flag)** Root cause: filtering ActionList children on every search keystroke changed the Dropdown's internal `options` array, corrupting the index-based selection (selectedIndices pointing to wrong entry in the shorter options list). Fixed by: - Rendering ALL countryData as ActionList children always. - Using the Dropdown context's setFilteredValues / setHasAutoCompleteInHeader (managed by new CountrySelectorSearch inner component) to control which rows are visible. This keeps `options` stable and also disables the built-in typeahead (hasAutoCompleteInHeader = true short-circuits onComboType), eliminating the desync entirely. **Bug 3 — No empty state when search has no results** ActionListNoResults was only rendered for dropdownTriggerer='AutoComplete'. Now it also fires when hasAutoCompleteInHeader is true. **Bug 4 — Dropdown disappears when typed text matches nothing** When all ActionListItems were filtered out, the overlay had zero visible content and appeared to vanish. Fixed as a side-effect of Bug 3: the empty ActionListNoResults component keeps the overlay content non-empty. **ActionListBox.web.tsx — non-virtualized mobile fix** Added useFilteredItems to ActionListNormalBox so mobile (BottomSheet, non-virtualized) also respects filteredValues from the Dropdown context, matching the existing behaviour of ActionListVirtualizedBox on desktop. Tests: added regression tests for all 4 bugs in CountrySelector.web.test.tsx. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…arch
Replace the custom CountrySelectorSearch TextInput implementation with
the existing AutoComplete component. This approach:
- Removes all custom keyboard handling, filteredValues wiring, and
hasAutoCompleteInHeader management — AutoComplete handles this
automatically when used in DropdownHeader / BottomSheetHeader
- Arrow key navigation, empty state, and auto-focus all work out of
the box via the existing Blade Dropdown + AutoComplete integration
- Keeps custom filtering logic for country name, ISO code, and dial
code (with or without +) via onInputValueChange + filteredValues
- isVirtualized={!isMobile} retained — virtualization ON for desktop,
OFF for mobile (avoids BottomSheet scroll conflict)
Problem
The country-selector in
PhoneNumberInputhad two related issues reported in Slack:isVirtualized={true}was set unconditionally, which conflicts with BottomSheet's own scroll and causes re-renders on every keystroke, making forms feel sluggish on Mweb.Changes
CountrySelector.web.tsxTextInputinDropdownHeader(desktop) andBottomSheetHeader(mobile)"india","IN","91","+91")isVirtualized={true}alwaysisVirtualized={!isMobile}— disabled on mobile, enabled on desktopDesktopSearchHeadercallssetHasAutoCompleteInHeader(true)so the Dropdown doesn'tpreventDefaultmouse-down in the header, allowing theTextInputto receive focusTests
New file:
CountrySelector.web.test.tsx++onCountryChangecallbackUpdated:
PhoneNumberInput.test.stories.tsxSearchByCountryName— open, type, pick a country, verify trigger label updatesSearchByDialCode— search with+prefixSearchResetOnClose— close via Escape, reopen, assert query clearedTesting
Storybook interaction tests:
Related
PaymentLinks/CreateV2/MWebContactDetails— consumer workaround (React.memo) can now be removedisVirtualized={!isMobile})🤖 Generated with Claude Code