get it somewhat working on web
This commit is contained in:
@@ -105,7 +105,8 @@ export type ButtonProps = Pick<
|
|||||||
PressableComponent?: React.ComponentType<PressableProps>
|
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>({
|
const Context = React.createContext<VariantProps & ButtonState>({
|
||||||
hovered: false,
|
hovered: false,
|
||||||
|
|||||||
@@ -6,9 +6,11 @@ import {useLingui} from '@lingui/react'
|
|||||||
import {getCountriesWithTelephoneCodes} from '#/lib/international-telephone-codes'
|
import {getCountriesWithTelephoneCodes} from '#/lib/international-telephone-codes'
|
||||||
import {isWeb} from '#/platform/detection'
|
import {isWeb} from '#/platform/detection'
|
||||||
import {useGeolocationStatus} from '#/state/geolocation'
|
import {useGeolocationStatus} from '#/state/geolocation'
|
||||||
import {atoms as a} from '#/alf'
|
import {atoms as a, web} from '#/alf'
|
||||||
import * as Select from '#/components/Select'
|
import * as Select from '#/components/Select'
|
||||||
|
|
||||||
|
export const DEFAULT_PHONE_COUNTRY = 'US'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Country picker for a phone number input
|
* Country picker for a phone number input
|
||||||
*
|
*
|
||||||
@@ -24,6 +26,9 @@ export function InternationalPhoneCodeSelect({
|
|||||||
}) {
|
}) {
|
||||||
const {_, i18n} = useLingui()
|
const {_, i18n} = useLingui()
|
||||||
const {location} = useGeolocationStatus()
|
const {location} = useGeolocationStatus()
|
||||||
|
|
||||||
|
const defaultCountry = location?.countryCode || DEFAULT_PHONE_COUNTRY
|
||||||
|
|
||||||
const items = useMemo(() => {
|
const items = useMemo(() => {
|
||||||
const telCountryMap = getCountriesWithTelephoneCodes(i18n)
|
const telCountryMap = getCountriesWithTelephoneCodes(i18n)
|
||||||
|
|
||||||
@@ -37,22 +42,25 @@ export function InternationalPhoneCodeSelect({
|
|||||||
unicodeFlag,
|
unicodeFlag,
|
||||||
svgFlag,
|
svgFlag,
|
||||||
}))
|
}))
|
||||||
// boost the default value to the top
|
// boost the default value to the top, then sort by name
|
||||||
.sort((a, b) =>
|
.sort((a, b) => {
|
||||||
a.value === location.countryCode
|
if (a.value === defaultCountry) return -1
|
||||||
? -1
|
if (b.value === defaultCountry) return 1
|
||||||
: b.value === location.countryCode
|
return a.name.localeCompare(b.name)
|
||||||
? 1
|
})
|
||||||
: 0,
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}, [i18n, location])
|
}, [i18n, defaultCountry])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Select.Root value={value} onValueChange={onChange}>
|
<Select.Root value={value} onValueChange={onChange}>
|
||||||
<Select.Trigger label={_(msg`Select telephone code`)}>
|
<Select.Trigger label={_(msg`Select telephone code`)}>
|
||||||
<Select.ValueText placeholder={_(msg`Select telephone code`)}>
|
<Select.ValueText placeholder="+...">
|
||||||
{item => item.unicodeFlag + ' ' + item.code}
|
{selected => (
|
||||||
|
<>
|
||||||
|
<Flag {...selected} />
|
||||||
|
{selected.code}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</Select.ValueText>
|
</Select.ValueText>
|
||||||
<Select.Icon />
|
<Select.Icon />
|
||||||
</Select.Trigger>
|
</Select.Trigger>
|
||||||
@@ -64,17 +72,11 @@ export function InternationalPhoneCodeSelect({
|
|||||||
<Select.Item value={item.value} label={item.label}>
|
<Select.Item value={item.value} label={item.label}>
|
||||||
<Select.ItemIndicator />
|
<Select.ItemIndicator />
|
||||||
<Select.ItemText style={[a.flex_1]} emoji>
|
<Select.ItemText style={[a.flex_1]} emoji>
|
||||||
{isWeb ? (
|
{isWeb ? <Flag {...item} /> : item.unicodeFlag + ' '}
|
||||||
<Image
|
|
||||||
source={item.svgFlag}
|
|
||||||
accessibilityIgnoresInvertColors
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
item.unicodeFlag + ' '
|
|
||||||
)}
|
|
||||||
{item.name}
|
{item.name}
|
||||||
</Select.ItemText>
|
</Select.ItemText>
|
||||||
<Select.ItemText style={[a.text_right]}>
|
<Select.ItemText style={[a.text_right]}>
|
||||||
|
{' '}
|
||||||
{item.code}
|
{item.code}
|
||||||
</Select.ItemText>
|
</Select.ItemText>
|
||||||
</Select.Item>
|
</Select.Item>
|
||||||
@@ -85,3 +87,20 @@ export function InternationalPhoneCodeSelect({
|
|||||||
</Select.Root>
|
</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()
|
const t = useTheme()
|
||||||
|
|
||||||
let text = value && children(value)
|
let text = value && children(value)
|
||||||
if (typeof text !== 'string') text = placeholder
|
if (!text) text = placeholder
|
||||||
|
|
||||||
return (
|
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 {
|
import {createContext, forwardRef, Fragment, useContext, useMemo} from 'react'
|
||||||
createContext,
|
|
||||||
type CSSProperties,
|
|
||||||
forwardRef,
|
|
||||||
Fragment,
|
|
||||||
useContext,
|
|
||||||
useMemo,
|
|
||||||
} from 'react'
|
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {Select as RadixSelect} from 'radix-ui'
|
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 {atoms as a} from '#/alf'
|
||||||
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
||||||
import {Check_Stroke2_Corner0_Rounded as CheckIcon} from '#/components/icons/Check'
|
import {Check_Stroke2_Corner0_Rounded as CheckIcon} from '#/components/icons/Check'
|
||||||
@@ -105,7 +99,6 @@ export function Trigger({children, label}: TriggerProps) {
|
|||||||
a.flex,
|
a.flex,
|
||||||
a.relative,
|
a.relative,
|
||||||
t.atoms.bg_contrast_50,
|
t.atoms.bg_contrast_50,
|
||||||
a.w_full,
|
|
||||||
a.align_center,
|
a.align_center,
|
||||||
a.gap_sm,
|
a.gap_sm,
|
||||||
a.justify_between,
|
a.justify_between,
|
||||||
@@ -153,6 +146,7 @@ export function Content<T>({
|
|||||||
}: ContentProps<T>) {
|
}: ContentProps<T>) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const selectedValue = useContext(SelectedValueContext)
|
const selectedValue = useContext(SelectedValueContext)
|
||||||
|
const {reduceMotionEnabled} = useA11y()
|
||||||
|
|
||||||
const scrollBtnStyles: React.CSSProperties[] = [
|
const scrollBtnStyles: React.CSSProperties[] = [
|
||||||
a.absolute,
|
a.absolute,
|
||||||
@@ -194,8 +188,11 @@ export function Content<T>({
|
|||||||
<RadixSelect.Content
|
<RadixSelect.Content
|
||||||
style={flatten([t.atoms.bg, a.rounded_sm, a.overflow_hidden])}
|
style={flatten([t.atoms.bg, a.rounded_sm, a.overflow_hidden])}
|
||||||
position="popper"
|
position="popper"
|
||||||
|
align="center"
|
||||||
sideOffset={5}
|
sideOffset={5}
|
||||||
className="radix-select-content">
|
className="radix-select-content"
|
||||||
|
// prevent the keyboard shortcut for opening the composer
|
||||||
|
onKeyDown={evt => evt.stopPropagation()}>
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
a.flex_1,
|
a.flex_1,
|
||||||
@@ -203,6 +200,7 @@ export function Content<T>({
|
|||||||
t.atoms.border_contrast_low,
|
t.atoms.border_contrast_low,
|
||||||
a.rounded_sm,
|
a.rounded_sm,
|
||||||
a.overflow_hidden,
|
a.overflow_hidden,
|
||||||
|
!reduceMotionEnabled && a.zoom_fade_in,
|
||||||
]}>
|
]}>
|
||||||
<RadixSelect.ScrollUpButton style={flatten(up)}>
|
<RadixSelect.ScrollUpButton style={flatten(up)}>
|
||||||
<ChevronUpIcon style={[t.atoms.text]} size="xs" />
|
<ChevronUpIcon style={[t.atoms.text]} size="xs" />
|
||||||
@@ -269,7 +267,7 @@ export function Item({ref, value, style, children}: ItemProps) {
|
|||||||
t.atoms.text,
|
t.atoms.text,
|
||||||
a.relative,
|
a.relative,
|
||||||
a.flex,
|
a.flex,
|
||||||
{minHeight: 25, paddingLeft: 30, paddingRight: 35},
|
{minHeight: 25, paddingLeft: 30, paddingRight: 8},
|
||||||
a.user_select_none,
|
a.user_select_none,
|
||||||
a.align_center,
|
a.align_center,
|
||||||
a.rounded_xs,
|
a.rounded_xs,
|
||||||
@@ -288,8 +286,10 @@ export function Item({ref, value, style, children}: ItemProps) {
|
|||||||
|
|
||||||
export const ItemText = function ItemText({children, style}: ItemTextProps) {
|
export const ItemText = function ItemText({children, style}: ItemTextProps) {
|
||||||
return (
|
return (
|
||||||
<RadixSelect.ItemText style={flatten(style) as CSSProperties}>
|
<RadixSelect.ItemText asChild>
|
||||||
{children}
|
<Text style={flatten([style, web({pointerEvents: 'inherit'})])}>
|
||||||
|
{children}
|
||||||
|
</Text>
|
||||||
</RadixSelect.ItemText>
|
</RadixSelect.ItemText>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ export type ValueProps = {
|
|||||||
/**
|
/**
|
||||||
* Only needed for native. Extracts the label from an item. Defaults to `item => item.label`
|
* 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
|
placeholder?: string
|
||||||
style?: StyleProp<TextStyle>
|
style?: StyleProp<TextStyle>
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user