Skip to content

Commit c394048

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 58e2e91 commit c394048

2 files changed

Lines changed: 68 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: 35 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,20 @@ 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 =
58+
item.isFeatured !== (previousItem || {}).isFeatured;
59+
60+
if (!isGroupBoundary) return '';
61+
62+
return item.isFeatured ? featuredOptionsLabel : otherOptionsLabel;
63+
};
4964

5065
const {
5166
getComboboxProps,
@@ -139,23 +154,25 @@ export const PhoneNumberInput = ({
139154
{...getComboboxProps()}
140155
data-testid="calling-code-input"
141156
>
142-
<S.CallingCodeFilterInputGroup>
143-
<S.CallingCodeFilterInput
144-
{...getInputProps(
145-
{
146-
placeholder: callingCodeFilterInputPlaceholder,
147-
},
148-
{ ...refErrorFix }
157+
{showFilterInput && (
158+
<S.CallingCodeFilterInputGroup>
159+
<S.CallingCodeFilterInput
160+
{...getInputProps(
161+
{
162+
placeholder: callingCodeFilterInputPlaceholder,
163+
},
164+
{ ...refErrorFix }
165+
)}
166+
ref={callingCodeFilterInputRef}
167+
data-testid="calling-code-filter-input"
168+
onFocus={onFocus}
169+
onBlur={onBlur}
170+
/>
171+
{isLoadingCallingCodeOptions && (
172+
<S.CallingCodeInputLoading data-testid="calling-code-options-loading" />
149173
)}
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>
174+
</S.CallingCodeFilterInputGroup>
175+
)}
159176
<S.CallingCodeOptionsList {...getMenuProps()}>
160177
{callingCodeOptions.length > 0 ? (
161178
callingCodeOptions.map((item, index) => (
@@ -166,11 +183,7 @@ export const PhoneNumberInput = ({
166183
index,
167184
})}
168185
title={item.label}
169-
withGroupHeader={
170-
item.isFeatured !==
171-
(callingCodeOptions[index - 1] || {}).isFeatured &&
172-
(item.isFeatured ? featuredOptionsLabel : otherOptionsLabel)
173-
}
186+
withGroupHeader={getGroupHeaderLabel(item, index)}
174187
>
175188
<Flex>
176189
<S.CallingCodeOptionCallingCode>
@@ -214,6 +227,7 @@ export interface Props {
214227
isDisableCallingCode?: boolean;
215228
isPlaceholderFloating?: boolean;
216229
isRequired?: boolean;
230+
showFilterInput?: boolean;
217231
}
218232

219233
export interface PhoneNumber {

0 commit comments

Comments
 (0)