get it somewhat working on web
This commit is contained in:
@@ -105,7 +105,8 @@ export type ButtonProps = Pick<
|
||||
PressableComponent?: React.ComponentType<PressableProps>
|
||||
}
|
||||
|
||||
export type ButtonTextProps = TextProps & VariantProps & {disabled?: boolean}
|
||||
export type ButtonTextProps = TextProps &
|
||||
VariantProps & {disabled?: boolean; emoji?: boolean}
|
||||
|
||||
const Context = React.createContext<VariantProps & ButtonState>({
|
||||
hovered: false,
|
||||
|
||||
@@ -6,9 +6,11 @@ import {useLingui} from '@lingui/react'
|
||||
import {getCountriesWithTelephoneCodes} from '#/lib/international-telephone-codes'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {useGeolocationStatus} from '#/state/geolocation'
|
||||
import {atoms as a} from '#/alf'
|
||||
import {atoms as a, web} from '#/alf'
|
||||
import * as Select from '#/components/Select'
|
||||
|
||||
export const DEFAULT_PHONE_COUNTRY = 'US'
|
||||
|
||||
/**
|
||||
* Country picker for a phone number input
|
||||
*
|
||||
@@ -24,6 +26,9 @@ export function InternationalPhoneCodeSelect({
|
||||
}) {
|
||||
const {_, i18n} = useLingui()
|
||||
const {location} = useGeolocationStatus()
|
||||
|
||||
const defaultCountry = location?.countryCode || DEFAULT_PHONE_COUNTRY
|
||||
|
||||
const items = useMemo(() => {
|
||||
const telCountryMap = getCountriesWithTelephoneCodes(i18n)
|
||||
|
||||
@@ -37,22 +42,25 @@ export function InternationalPhoneCodeSelect({
|
||||
unicodeFlag,
|
||||
svgFlag,
|
||||
}))
|
||||
// boost the default value to the top
|
||||
.sort((a, b) =>
|
||||
a.value === location.countryCode
|
||||
? -1
|
||||
: b.value === location.countryCode
|
||||
? 1
|
||||
: 0,
|
||||
)
|
||||
// boost the default value to the top, then sort by name
|
||||
.sort((a, b) => {
|
||||
if (a.value === defaultCountry) return -1
|
||||
if (b.value === defaultCountry) return 1
|
||||
return a.name.localeCompare(b.name)
|
||||
})
|
||||
)
|
||||
}, [i18n, location])
|
||||
}, [i18n, defaultCountry])
|
||||
|
||||
return (
|
||||
<Select.Root value={value} onValueChange={onChange}>
|
||||
<Select.Trigger label={_(msg`Select telephone code`)}>
|
||||
<Select.ValueText placeholder={_(msg`Select telephone code`)}>
|
||||
{item => item.unicodeFlag + ' ' + item.code}
|
||||
<Select.ValueText placeholder="+...">
|
||||
{selected => (
|
||||
<>
|
||||
<Flag {...selected} />
|
||||
{selected.code}
|
||||
</>
|
||||
)}
|
||||
</Select.ValueText>
|
||||
<Select.Icon />
|
||||
</Select.Trigger>
|
||||
@@ -64,17 +72,11 @@ export function InternationalPhoneCodeSelect({
|
||||
<Select.Item value={item.value} label={item.label}>
|
||||
<Select.ItemIndicator />
|
||||
<Select.ItemText style={[a.flex_1]} emoji>
|
||||
{isWeb ? (
|
||||
<Image
|
||||
source={item.svgFlag}
|
||||
accessibilityIgnoresInvertColors
|
||||
/>
|
||||
) : (
|
||||
item.unicodeFlag + ' '
|
||||
)}
|
||||
{isWeb ? <Flag {...item} /> : item.unicodeFlag + ' '}
|
||||
{item.name}
|
||||
</Select.ItemText>
|
||||
<Select.ItemText style={[a.text_right]}>
|
||||
{' '}
|
||||
{item.code}
|
||||
</Select.ItemText>
|
||||
</Select.Item>
|
||||
@@ -85,3 +87,20 @@ export function InternationalPhoneCodeSelect({
|
||||
</Select.Root>
|
||||
)
|
||||
}
|
||||
|
||||
function Flag({unicodeFlag, svgFlag}: {unicodeFlag: string; svgFlag: any}) {
|
||||
if (isWeb) {
|
||||
return (
|
||||
<Image
|
||||
source={svgFlag}
|
||||
style={[
|
||||
a.rounded_2xs,
|
||||
{height: 13, aspectRatio: 4 / 3, marginRight: 6},
|
||||
web({verticalAlign: 'bottom'}),
|
||||
]}
|
||||
accessibilityIgnoresInvertColors
|
||||
/>
|
||||
)
|
||||
}
|
||||
return unicodeFlag + ' '
|
||||
}
|
||||
|
||||
@@ -122,10 +122,12 @@ export function ValueText({
|
||||
const t = useTheme()
|
||||
|
||||
let text = value && children(value)
|
||||
if (typeof text !== 'string') text = placeholder
|
||||
if (!text) text = placeholder
|
||||
|
||||
return (
|
||||
<ButtonText style={[t.atoms.text, a.font_normal, style]}>{text}</ButtonText>
|
||||
<ButtonText style={[t.atoms.text, a.font_normal, style]} emoji>
|
||||
{text}
|
||||
</ButtonText>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
import {
|
||||
createContext,
|
||||
type CSSProperties,
|
||||
forwardRef,
|
||||
Fragment,
|
||||
useContext,
|
||||
useMemo,
|
||||
} from 'react'
|
||||
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'
|
||||
@@ -105,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,
|
||||
@@ -153,6 +146,7 @@ export function Content<T>({
|
||||
}: ContentProps<T>) {
|
||||
const t = useTheme()
|
||||
const selectedValue = useContext(SelectedValueContext)
|
||||
const {reduceMotionEnabled} = useA11y()
|
||||
|
||||
const scrollBtnStyles: React.CSSProperties[] = [
|
||||
a.absolute,
|
||||
@@ -194,8 +188,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,
|
||||
@@ -203,6 +200,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" />
|
||||
@@ -269,7 +267,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,
|
||||
@@ -288,8 +286,10 @@ export function Item({ref, value, style, children}: ItemProps) {
|
||||
|
||||
export const ItemText = function ItemText({children, style}: ItemTextProps) {
|
||||
return (
|
||||
<RadixSelect.ItemText style={flatten(style) as CSSProperties}>
|
||||
{children}
|
||||
<RadixSelect.ItemText asChild>
|
||||
<Text style={flatten([style, web({pointerEvents: 'inherit'})])}>
|
||||
{children}
|
||||
</Text>
|
||||
</RadixSelect.ItemText>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ export type ValueProps = {
|
||||
/**
|
||||
* Only needed for native. Extracts the label from an item. Defaults to `item => item.label`
|
||||
*/
|
||||
children?: (value: any) => string
|
||||
children?: (value: any) => React.ReactNode
|
||||
placeholder?: string
|
||||
style?: StyleProp<TextStyle>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user