diff --git a/.changeset/quiet-flags-phone.md b/.changeset/quiet-flags-phone.md new file mode 100644 index 00000000000..a845151cc84 --- /dev/null +++ b/.changeset/quiet-flags-phone.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/packages/mosaic/src/components/phone-input/phone-input.styles.ts b/packages/mosaic/src/components/phone-input/phone-input.styles.ts index 23a6f199762..f3de00abba9 100644 --- a/packages/mosaic/src/components/phone-input/phone-input.styles.ts +++ b/packages/mosaic/src/components/phone-input/phone-input.styles.ts @@ -1,6 +1,6 @@ import * as stylex from '@stylexjs/stylex'; -import { colorVars, radiusVars, shadowVars, space, typeScaleVars } from '../../tokens.stylex'; +import { colorVars, radiusVars, shadowVars, space } from '../../tokens.stylex'; export const styles = stylex.create({ triggerContent: { @@ -9,15 +9,8 @@ export const styles = stylex.create({ display: 'flex', }, flag: { - fontSize: typeScaleVars['--cl-text-sm-size'], - lineHeight: 1, - }, - triggerFlag: { - alignItems: 'center', - display: 'flex', + display: 'block', flexShrink: 0, - fontSize: space['4'], - justifyContent: 'center', height: space['4'], width: space['4'], }, diff --git a/packages/mosaic/src/components/phone-input/phone-input.test.tsx b/packages/mosaic/src/components/phone-input/phone-input.test.tsx index 859585380a7..1707a3ff685 100644 --- a/packages/mosaic/src/components/phone-input/phone-input.test.tsx +++ b/packages/mosaic/src/components/phone-input/phone-input.test.tsx @@ -7,6 +7,41 @@ import { Field } from '../field'; import { PhoneInput } from './phone-input'; describe('Mosaic PhoneInput', () => { + it('renders SVG country flags and updates the selected flag after choosing a country', async () => { + const user = userEvent.setup(); + render(); + + const trigger = screen.getByRole('button', { name: 'Country, United States' }); + await waitFor(() => expect(trigger.querySelector('svg.cl-phone-input-flag path[fill="#D80027"]')).not.toBeNull()); + const selectedFlagArtwork = trigger.querySelector('svg.cl-phone-input-flag')?.innerHTML; + expect(trigger.querySelector('svg.cl-phone-input-flag')).toHaveAttribute('viewBox', '0 0 16 16'); + expect(trigger.querySelector('svg.cl-phone-input-flag')).toHaveAttribute('aria-hidden', 'true'); + expect(trigger).not.toHaveTextContent('🇺🇸'); + + await user.click(trigger); + + for (const option of screen.getAllByRole('option')) { + expect(option.querySelector('svg.cl-phone-input-flag')).toHaveAttribute('aria-hidden', 'true'); + expect(option).not.toHaveTextContent(/\p{Regional_Indicator}/u); + } + + const japan = screen.getByRole('option', { name: /Japan/ }); + await waitFor(() => expect(japan.querySelector('svg.cl-phone-input-flag path[d^="M8.00001"]')).not.toBeNull()); + const japanArtwork = japan.querySelector('svg.cl-phone-input-flag')?.innerHTML; + expect(japanArtwork).toBeTruthy(); + expect(japanArtwork).not.toBe(selectedFlagArtwork); + + await user.type(screen.getByRole('combobox', { name: 'Search countries' }), 'Japan'); + await user.keyboard('{ArrowDown}{Enter}'); + + await waitFor(() => + expect( + screen.getByRole('button', { name: 'Country, Japan' }).querySelector('svg.cl-phone-input-flag')?.innerHTML, + ).toBe(japanArtwork), + ); + expect(screen.getByRole('textbox', { name: 'Phone number' })).toHaveFocus(); + }); + it('focuses the country search when opened with a pointer', async () => { const user = userEvent.setup(); render(); diff --git a/packages/mosaic/src/components/phone-input/phone-input.tsx b/packages/mosaic/src/components/phone-input/phone-input.tsx index c3b1e499203..a675216218e 100644 --- a/packages/mosaic/src/components/phone-input/phone-input.tsx +++ b/packages/mosaic/src/components/phone-input/phone-input.tsx @@ -1,17 +1,12 @@ 'use client'; import type { CountryEntry, CountryIso } from '@clerk/shared/phone'; -import { - extractDigits, - formatPhoneNumber, - getFlagEmojiFromCountryIso, - IsoToCountryMap, - parsePhoneString, -} from '@clerk/shared/phone'; +import { extractDigits, formatPhoneNumber, IsoToCountryMap, parsePhoneString } from '@clerk/shared/phone'; import { useMergeRefs } from '@floating-ui/react'; import * as stylex from '@stylexjs/stylex'; import React from 'react'; +import { CountryFlag } from '../../icons/country-flags'; import type { MosaicElementProps } from '../../props'; import { mergeStyleProps, themeProps } from '../../props'; import { reset } from '../../utils/reset.styles'; @@ -210,15 +205,11 @@ export const PhoneInput = React.forwardRef(fu aria-label={`Country, ${country.name}`} > - + {...mergeStyleProps(themeProps('phone-input-flag'), stylex.props(reset.base, styles.flag))} + /> (fu {filteredCountries.length > 0 ? ( - filteredCountries.map(option => ( - - - {option.name} - +{option.code} - - - - - )) +