Skip to content

Commit da92469

Browse files
committed
Improve PhoneNumberInput
- Allow show/hide the search bar, defaults to show to keep backwards compatibilty - Hide others/features label if there is only one type of options.
1 parent d335725 commit da92469

2 files changed

Lines changed: 67 additions & 21 deletions

File tree

src/Input/PhoneNumberInput/PhoneNumberInput.test.tsx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,39 @@ describe('<PhoneNumberInput>', () => {
191191
);
192192
});
193193

194+
it('should render group headers when options include both featured and non-featured', () => {
195+
const { getToggleButton, getCallingCodeOptions } = renderComponent();
196+
fireEvent.click(getToggleButton());
197+
const [firstOption, secondOption] = getCallingCodeOptions();
198+
expect(firstOption.className).not.toEqual(secondOption.className);
199+
});
200+
201+
it('should not render group headers when all options are featured', () => {
202+
const featuredOnlyCallingCodeOptions = [
203+
{ label: 'Indonesia', callingCode: 62, isFeatured: true },
204+
{ label: 'Malaysia', callingCode: 60, isFeatured: true },
205+
];
206+
const { getToggleButton, getCallingCodeOptions } = renderComponent({
207+
callingCodeOptions: featuredOnlyCallingCodeOptions,
208+
});
209+
fireEvent.click(getToggleButton());
210+
const [firstOption, secondOption] = getCallingCodeOptions();
211+
expect(firstOption.className).toEqual(secondOption.className);
212+
});
213+
214+
it('should not render group headers when all options are non-featured', () => {
215+
const nonFeaturedOnlyCallingCodeOptions = [
216+
{ label: 'Afghanistan', callingCode: 93, isFeatured: false },
217+
{ label: 'Albania', callingCode: 355, isFeatured: false },
218+
];
219+
const { getToggleButton, getCallingCodeOptions } = renderComponent({
220+
callingCodeOptions: nonFeaturedOnlyCallingCodeOptions,
221+
});
222+
fireEvent.click(getToggleButton());
223+
const [firstOption, secondOption] = getCallingCodeOptions();
224+
expect(firstOption.className).toEqual(secondOption.className);
225+
});
226+
194227
it('should focus the calling code filter input on clicking the toggle button', () => {
195228
const { getToggleButton, getCallingCodeFilterInput } = renderComponent();
196229
fireEvent.click(getToggleButton());

src/Input/PhoneNumberInput/PhoneNumberInput.tsx

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export const PhoneNumberInput = ({
3434
isRequired,
3535
error,
3636
addon,
37+
showFilterInput = false,
3738
...restProps
3839
}: Props) => {
3940
const [isCallingCodeInputOpen, setIsCallingCodeInputOpen] = useState(false);
@@ -46,6 +47,19 @@ export const PhoneNumberInput = ({
4647
['isFeatured', 'label'],
4748
['desc', 'asc']
4849
);
50+
const hasFeaturedOptions = callingCodeOptions.some(item => item.isFeatured);
51+
const hasOtherOptions = callingCodeOptions.some(item => !item.isFeatured);
52+
const shouldShowGroupHeaders = hasFeaturedOptions && hasOtherOptions;
53+
const getGroupHeaderLabel = (item: CallingCodeOption, index: number) => {
54+
if (!shouldShowGroupHeaders) return '';
55+
56+
const previousItem = callingCodeOptions[index - 1];
57+
const isGroupBoundary = item.isFeatured !== (previousItem || {}).isFeatured;
58+
59+
if (!isGroupBoundary) return '';
60+
61+
return item.isFeatured ? featuredOptionsLabel : otherOptionsLabel;
62+
};
4963

5064
const {
5165
getComboboxProps,
@@ -139,23 +153,25 @@ export const PhoneNumberInput = ({
139153
{...getComboboxProps()}
140154
data-testid="calling-code-input"
141155
>
142-
<S.CallingCodeFilterInputGroup>
143-
<S.CallingCodeFilterInput
144-
{...getInputProps(
145-
{
146-
placeholder: callingCodeFilterInputPlaceholder,
147-
},
148-
{ ...refErrorFix }
156+
{showFilterInput && (
157+
<S.CallingCodeFilterInputGroup>
158+
<S.CallingCodeFilterInput
159+
{...getInputProps(
160+
{
161+
placeholder: callingCodeFilterInputPlaceholder,
162+
},
163+
{ ...refErrorFix }
164+
)}
165+
ref={callingCodeFilterInputRef}
166+
data-testid="calling-code-filter-input"
167+
onFocus={onFocus}
168+
onBlur={onBlur}
169+
/>
170+
{isLoadingCallingCodeOptions && (
171+
<S.CallingCodeInputLoading data-testid="calling-code-options-loading" />
149172
)}
150-
ref={callingCodeFilterInputRef}
151-
data-testid="calling-code-filter-input"
152-
onFocus={onFocus}
153-
onBlur={onBlur}
154-
/>
155-
{isLoadingCallingCodeOptions && (
156-
<S.CallingCodeInputLoading data-testid="calling-code-options-loading" />
157-
)}
158-
</S.CallingCodeFilterInputGroup>
173+
</S.CallingCodeFilterInputGroup>
174+
)}
159175
<S.CallingCodeOptionsList {...getMenuProps()}>
160176
{callingCodeOptions.length > 0 ? (
161177
callingCodeOptions.map((item, index) => (
@@ -166,11 +182,7 @@ export const PhoneNumberInput = ({
166182
index,
167183
})}
168184
title={item.label}
169-
withGroupHeader={
170-
item.isFeatured !==
171-
(callingCodeOptions[index - 1] || {}).isFeatured &&
172-
(item.isFeatured ? featuredOptionsLabel : otherOptionsLabel)
173-
}
185+
withGroupHeader={getGroupHeaderLabel(item, index)}
174186
>
175187
<Flex>
176188
<S.CallingCodeOptionCallingCode>
@@ -214,6 +226,7 @@ export interface Props {
214226
isDisableCallingCode?: boolean;
215227
isPlaceholderFloating?: boolean;
216228
isRequired?: boolean;
229+
showFilterInput?: boolean;
217230
}
218231

219232
export interface PhoneNumber {

0 commit comments

Comments
 (0)