Move Dialogs to Radix (#5648)

* Use Redix FocusTrap (#5638)

* Use Redix FocusTrap

* force resolutions on radix libs

* add focus guards

* use @radix-ui/dismissable-layer for escape handling

* fix banner menu keypress by using `Pressable`

* add menu in dialog example to storybook

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>

* use DismissableLayer/FocusScope for composer

* fix storybook dialog

* thread Portal through Prompt and avatar/banner

* fix dialog style regression

* remove tamagui

---------

Co-authored-by: Eric Bailey <git@esb.lol>
This commit is contained in:
Samuel Newman
2024-10-08 20:00:49 +03:00
committed by GitHub
parent efcf8a6ae5
commit fc82d2f6d5
14 changed files with 383 additions and 443 deletions
+7 -7
View File
@@ -1,5 +1,5 @@
import React, {memo, useMemo} from 'react'
import {Image, StyleSheet, TouchableOpacity, View} from 'react-native'
import {Image, Pressable, StyleSheet, View} from 'react-native'
import {Image as RNImage} from 'react-native-image-crop-picker'
import Svg, {Circle, Path, Rect} from 'react-native-svg'
import {AppBskyActorDefs, ModerationUI} from '@atproto/api'
@@ -30,6 +30,7 @@ import {Trash_Stroke2_Corner0_Rounded as Trash} from '#/components/icons/Trash'
import {Link} from '#/components/Link'
import {MediaInsetBorder} from '#/components/MediaInsetBorder'
import * as Menu from '#/components/Menu'
import {PortalComponent} from '#/components/Portal'
import {ProfileHoverCard} from '#/components/ProfileHoverCard'
import {openCamera, openCropper, openPicker} from '../../../lib/media/picker'
@@ -50,6 +51,7 @@ interface UserAvatarProps extends BaseUserAvatarProps {
interface EditableUserAvatarProps extends BaseUserAvatarProps {
onSelectNewAvatar: (img: RNImage | null) => void
Portal?: PortalComponent
}
interface PreviewableUserAvatarProps extends BaseUserAvatarProps {
@@ -266,6 +268,7 @@ let EditableUserAvatar = ({
size,
avatar,
onSelectNewAvatar,
Portal,
}: EditableUserAvatarProps): React.ReactNode => {
const t = useTheme()
const pal = usePalette('default')
@@ -346,10 +349,7 @@ let EditableUserAvatar = ({
<Menu.Root>
<Menu.Trigger label={_(msg`Edit avatar`)}>
{({props}) => (
<TouchableOpacity
{...props}
activeOpacity={0.8}
testID="changeAvatarBtn">
<Pressable {...props} testID="changeAvatarBtn">
{avatar ? (
<HighPriorityImage
testID="userAvatarImage"
@@ -363,10 +363,10 @@ let EditableUserAvatar = ({
<View style={[styles.editButtonContainer, pal.btn]}>
<CameraFilled height={14} width={14} style={t.atoms.text} />
</View>
</TouchableOpacity>
</Pressable>
)}
</Menu.Trigger>
<Menu.Outer showCancel>
<Menu.Outer showCancel Portal={Portal}>
<Menu.Group>
{isNative && (
<Menu.Item
+8 -8
View File
@@ -1,5 +1,5 @@
import React from 'react'
import {StyleSheet, TouchableOpacity, View} from 'react-native'
import {Pressable, StyleSheet, View} from 'react-native'
import {Image as RNImage} from 'react-native-image-crop-picker'
import {Image} from 'expo-image'
import {ModerationUI} from '@atproto/api'
@@ -25,6 +25,7 @@ import {
import {StreamingLive_Stroke2_Corner0_Rounded as Library} from '#/components/icons/StreamingLive'
import {Trash_Stroke2_Corner0_Rounded as Trash} from '#/components/icons/Trash'
import * as Menu from '#/components/Menu'
import {PortalComponent} from '#/components/Portal'
import {openCamera, openCropper, openPicker} from '../../../lib/media/picker'
export function UserBanner({
@@ -32,11 +33,13 @@ export function UserBanner({
banner,
moderation,
onSelectNewBanner,
Portal,
}: {
type?: 'labeler' | 'default'
banner?: string | null
moderation?: ModerationUI
onSelectNewBanner?: (img: RNImage | null) => void
Portal?: PortalComponent
}) {
const pal = usePalette('default')
const theme = useTheme()
@@ -90,14 +93,11 @@ export function UserBanner({
// setUserBanner is only passed as prop on the EditProfile component
return onSelectNewBanner ? (
<EventStopper onKeyDown={false}>
<EventStopper onKeyDown={true}>
<Menu.Root>
<Menu.Trigger label={_(msg`Edit avatar`)}>
{({props}) => (
<TouchableOpacity
{...props}
activeOpacity={0.8}
testID="changeBannerBtn">
<Pressable {...props} testID="changeBannerBtn">
{banner ? (
<Image
testID="userBannerImage"
@@ -115,10 +115,10 @@ export function UserBanner({
<View style={[styles.editButtonContainer, pal.btn]}>
<CameraFilled height={14} width={14} style={t.atoms.text} />
</View>
</TouchableOpacity>
</Pressable>
)}
</Menu.Trigger>
<Menu.Outer showCancel>
<Menu.Outer showCancel Portal={Portal}>
<Menu.Group>
{isNative && (
<Menu.Item