Telephone country code select (#9473)

* add telephone code select

* add flags

* run svgo on flags

* get it somewhat working on web

* get web closed state working

* verify country code we get from geo

* trim down names to shorter common versions

* add labels to other selects

* make international tel codes a static object

* add component to storybook

* Update src/lib/international-telephone-codes.ts

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* update to new geo hook

* use Intl.DisplayNames, add polyfill

* use in rather than keys().includes()

---------

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
This commit is contained in:
Samuel Newman
2025-12-10 22:12:30 +02:00
committed by GitHub
parent 07e1b3a0b6
commit 6ccda945e5
280 changed files with 1995 additions and 112 deletions
+49 -7
View File
@@ -2,7 +2,8 @@ import {createContext, forwardRef, Fragment, useContext, useMemo} from 'react'
import {View} from 'react-native'
import {Select as RadixSelect} from 'radix-ui'
import {flatten, useTheme} from '#/alf'
import {useA11y} from '#/state/a11y'
import {flatten, useTheme, web} from '#/alf'
import {atoms as a} from '#/alf'
import {useInteractionState} from '#/components/hooks/useInteractionState'
import {Check_Stroke2_Corner0_Rounded as CheckIcon} from '#/components/icons/Check'
@@ -16,6 +17,7 @@ import {
type IconProps,
type ItemIndicatorProps,
type ItemProps,
type ItemTextProps,
type RadixPassThroughTriggerProps,
type RootProps,
type TriggerProps,
@@ -97,7 +99,6 @@ export function Trigger({children, label}: TriggerProps) {
a.flex,
a.relative,
t.atoms.bg_contrast_50,
a.w_full,
a.align_center,
a.gap_sm,
a.justify_between,
@@ -121,10 +122,21 @@ export function Trigger({children, label}: TriggerProps) {
}
}
export function ValueText({children: _, style, ...props}: ValueProps) {
export function ValueText({
children,
webOverrideValue,
style,
...props
}: ValueProps) {
let content
if (webOverrideValue && children) {
content = children(webOverrideValue)
}
return (
<Text style={style}>
<RadixSelect.Value {...props} />
<RadixSelect.Value {...props}>{content}</RadixSelect.Value>
</Text>
)
}
@@ -145,6 +157,7 @@ export function Content<T>({
}: ContentProps<T>) {
const t = useTheme()
const selectedValue = useContext(SelectedValueContext)
const {reduceMotionEnabled} = useA11y()
const scrollBtnStyles: React.CSSProperties[] = [
a.absolute,
@@ -186,8 +199,11 @@ export function Content<T>({
<RadixSelect.Content
style={flatten([t.atoms.bg, a.rounded_sm, a.overflow_hidden])}
position="popper"
align="center"
sideOffset={5}
className="radix-select-content">
className="radix-select-content"
// prevent the keyboard shortcut for opening the composer
onKeyDown={evt => evt.stopPropagation()}>
<View
style={[
a.flex_1,
@@ -195,6 +211,7 @@ export function Content<T>({
t.atoms.border_contrast_low,
a.rounded_sm,
a.overflow_hidden,
!reduceMotionEnabled && a.zoom_fade_in,
]}>
<RadixSelect.ScrollUpButton style={flatten(up)}>
<ChevronUpIcon style={[t.atoms.text]} size="xs" />
@@ -261,7 +278,7 @@ export function Item({ref, value, style, children}: ItemProps) {
t.atoms.text,
a.relative,
a.flex,
{minHeight: 25, paddingLeft: 30, paddingRight: 35},
{minHeight: 25, paddingLeft: 30, paddingRight: 8},
a.user_select_none,
a.align_center,
a.rounded_xs,
@@ -278,7 +295,15 @@ export function Item({ref, value, style, children}: ItemProps) {
)
}
export const ItemText = RadixSelect.ItemText
export const ItemText = function ItemText({children, style}: ItemTextProps) {
return (
<RadixSelect.ItemText asChild>
<Text style={flatten([style, web({pointerEvents: 'inherit'})])}>
{children}
</Text>
</RadixSelect.ItemText>
)
}
export function ItemIndicator({icon: Icon = CheckIcon}: ItemIndicatorProps) {
return (
@@ -294,3 +319,20 @@ export function ItemIndicator({icon: Icon = CheckIcon}: ItemIndicatorProps) {
</RadixSelect.ItemIndicator>
)
}
export function Separator() {
const t = useTheme()
return (
<RadixSelect.Separator
style={flatten([
{
height: 1,
backgroundColor: t.atoms.border_contrast_low.borderColor,
},
a.my_xs,
a.w_full,
])}
/>
)
}