Keep all radix dependencies aligned by using single package (#8219)

* keep all radix deps aligned by using single package

* import directly from `radix-ui` or `radix-ui/internal`

* prevent radix leaking into native build
This commit is contained in:
Samuel Newman
2025-04-25 00:15:46 +03:00
committed by GitHub
parent b6a6b1bab4
commit 278a54850b
14 changed files with 756 additions and 189 deletions
+12 -14
View File
@@ -1,17 +1,15 @@
import React, {useImperativeHandle} from 'react'
import {
FlatList,
FlatListProps,
StyleProp,
type FlatListProps,
type StyleProp,
TouchableWithoutFeedback,
View,
ViewStyle,
type ViewStyle,
} from 'react-native'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {DismissableLayer} from '@radix-ui/react-dismissable-layer'
import {useFocusGuards} from '@radix-ui/react-focus-guards'
import {FocusScope} from '@radix-ui/react-focus-scope'
import {DismissableLayer, FocusGuards, FocusScope} from 'radix-ui/internal'
import {RemoveScrollBar} from 'react-remove-scroll-bar'
import {logger} from '#/logger'
@@ -21,9 +19,9 @@ import {atoms as a, flatten, useBreakpoints, useTheme, web} from '#/alf'
import {Button, ButtonIcon} from '#/components/Button'
import {Context} from '#/components/Dialog/context'
import {
DialogControlProps,
DialogInnerProps,
DialogOuterProps,
type DialogControlProps,
type DialogInnerProps,
type DialogOuterProps,
} from '#/components/Dialog/types'
import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
import {Portal} from '#/components/Portal'
@@ -162,9 +160,9 @@ export function Inner({
const {close} = React.useContext(Context)
const {gtMobile} = useBreakpoints()
const {reduceMotionEnabled} = useA11y()
useFocusGuards()
FocusGuards.useFocusGuards()
return (
<FocusScope loop asChild trapped>
<FocusScope.FocusScope loop asChild trapped>
<View
role="dialog"
aria-role="dialog"
@@ -191,7 +189,7 @@ export function Inner({
!reduceMotionEnabled && a.zoom_fade_in,
style,
])}>
<DismissableLayer
<DismissableLayer.DismissableLayer
onInteractOutside={preventDefault}
onFocusOutside={preventDefault}
onDismiss={close}
@@ -200,9 +198,9 @@ export function Inner({
<View style={[gtMobile ? a.p_2xl : a.p_xl, contentContainerStyle]}>
{children}
</View>
</DismissableLayer>
</DismissableLayer.DismissableLayer>
</View>
</FocusScope>
</FocusScope.FocusScope>
)
}
+10 -10
View File
@@ -1,12 +1,12 @@
import React from 'react'
import {Pressable, StyleProp, View, ViewStyle} from 'react-native'
import {Pressable, type StyleProp, View, type ViewStyle} from 'react-native'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
import {DropdownMenu} from 'radix-ui'
import {useA11y} from '#/state/a11y'
import {atoms as a, flatten, useTheme, web} from '#/alf'
import * as Dialog from '#/components/Dialog'
import type * as Dialog from '#/components/Dialog'
import {useInteractionState} from '#/components/hooks/useInteractionState'
import {
Context,
@@ -15,13 +15,13 @@ import {
useMenuItemContext,
} from '#/components/Menu/context'
import {
ContextType,
GroupProps,
ItemIconProps,
ItemProps,
ItemTextProps,
RadixPassThroughTriggerProps,
TriggerProps,
type ContextType,
type GroupProps,
type ItemIconProps,
type ItemProps,
type ItemTextProps,
type RadixPassThroughTriggerProps,
type TriggerProps,
} from '#/components/Menu/types'
import {Portal} from '#/components/Portal'
import {Text} from '#/components/Typography'
@@ -4,10 +4,10 @@ import {type ChatBskyConvoDefs} from '@atproto/api'
import EmojiPicker from '@emoji-mart/react'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
import {DropdownMenu} from 'radix-ui'
import {useSession} from '#/state/session'
import {type Emoji} from '#/view/com/composer/text-input/web/EmojiPicker.web'
import {type Emoji} from '#/view/com/composer/text-input/web/EmojiPicker'
import {useWebPreloadEmoji} from '#/view/com/composer/text-input/web/useWebPreloadEmoji'
import {atoms as a, flatten, useTheme} from '#/alf'
import {DotGrid_Stroke2_Corner0_Rounded as DotGridIcon} from '#/components/icons/DotGrid'
@@ -24,7 +24,7 @@ import {
useMessageDraft,
useSaveMessageDraft,
} from '#/state/messages/message-drafts'
import {type EmojiPickerPosition} from '#/view/com/composer/text-input/web/EmojiPicker.web'
import {type EmojiPickerPosition} from '#/view/com/composer/text-input/web/EmojiPicker'
import * as Toast from '#/view/com/util/Toast'
import {android, atoms as a, useTheme} from '#/alf'
import {useSharedInputStyles} from '#/components/forms/TextField'
@@ -15,9 +15,9 @@ import {
} from '#/state/messages/message-drafts'
import {textInputWebEmitter} from '#/view/com/composer/text-input/textInputWebEmitter'
import {
Emoji,
EmojiPickerPosition,
} from '#/view/com/composer/text-input/web/EmojiPicker.web'
type Emoji,
type EmojiPickerPosition,
} from '#/view/com/composer/text-input/web/EmojiPicker'
import * as Toast from '#/view/com/util/Toast'
import {atoms as a, useTheme} from '#/alf'
import {Button} from '#/components/Button'
@@ -1,5 +1,5 @@
import {useCallback, useEffect, useRef, useState} from 'react'
import {LayoutChangeEvent, View} from 'react-native'
import {type LayoutChangeEvent, View} from 'react-native'
import {useKeyboardHandler} from 'react-native-keyboard-controller'
import Animated, {
runOnJS,
@@ -8,10 +8,10 @@ import Animated, {
useAnimatedStyle,
useSharedValue,
} from 'react-native-reanimated'
import {ReanimatedScrollEvent} from 'react-native-reanimated/lib/typescript/hook/commonTypes'
import {type ReanimatedScrollEvent} from 'react-native-reanimated/lib/typescript/hook/commonTypes'
import {
$Typed,
AppBskyEmbedRecord,
type $Typed,
type AppBskyEmbedRecord,
AppBskyRichtextFacet,
RichText,
} from '@atproto/api'
@@ -26,19 +26,23 @@ import {logger} from '#/logger'
import {isNative} from '#/platform/detection'
import {isWeb} from '#/platform/detection'
import {
ActiveConvoStates,
type ActiveConvoStates,
isConvoActive,
useConvoActive,
} from '#/state/messages/convo'
import {ConvoItem, ConvoState, ConvoStatus} from '#/state/messages/convo/types'
import {
type ConvoItem,
type ConvoState,
ConvoStatus,
} from '#/state/messages/convo/types'
import {useGetPost} from '#/state/queries/post'
import {useAgent} from '#/state/session'
import {useShellLayout} from '#/state/shell/shell-layout'
import {
EmojiPicker,
EmojiPickerState,
} from '#/view/com/composer/text-input/web/EmojiPicker.web'
import {List, ListMethods} from '#/view/com/util/List'
type EmojiPickerState,
} from '#/view/com/composer/text-input/web/EmojiPicker'
import {List, type ListMethods} from '#/view/com/util/List'
import {ChatDisabled} from '#/screens/Messages/components/ChatDisabled'
import {MessageInput} from '#/screens/Messages/components/MessageInput'
import {MessageListError} from '#/screens/Messages/components/MessageListError'
+4 -4
View File
@@ -1,8 +1,8 @@
import React from 'react'
import {
AppBskyActorDefs,
AppBskyFeedDefs,
ModerationDecision,
type AppBskyActorDefs,
type AppBskyFeedDefs,
type ModerationDecision,
} from '@atproto/api'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
@@ -12,7 +12,7 @@ import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
import {postUriToRelativePath, toBskyAppUrl} from '#/lib/strings/url-helpers'
import {purgeTemporaryImageFiles} from '#/state/gallery'
import {precacheResolveLinkQuery} from '#/state/queries/resolve-link'
import type {EmojiPickerPosition} from '#/view/com/composer/text-input/web/EmojiPicker.web'
import {type EmojiPickerPosition} from '#/view/com/composer/text-input/web/EmojiPicker'
import * as Toast from '#/view/com/util/Toast'
export interface ComposerOptsPostRef {
@@ -12,14 +12,14 @@ import {Placeholder} from '@tiptap/extension-placeholder'
import {Text as TiptapText} from '@tiptap/extension-text'
import {generateJSON} from '@tiptap/html'
import {Fragment, Node, Slice} from '@tiptap/pm/model'
import {EditorContent, JSONContent, useEditor} from '@tiptap/react'
import {EditorContent, type JSONContent, useEditor} from '@tiptap/react'
import {useColorSchemeStyle} from '#/lib/hooks/useColorSchemeStyle'
import {usePalette} from '#/lib/hooks/usePalette'
import {blobToDataUri, isUriImage} from '#/lib/media/util'
import {useActorAutocompleteFn} from '#/state/queries/actor-autocomplete'
import {
LinkFacetMatch,
type LinkFacetMatch,
suggestLinkCardUri,
} from '#/view/com/composer/text-input/text-input-util'
import {textInputWebEmitter} from '#/view/com/composer/text-input/textInputWebEmitter'
@@ -28,7 +28,7 @@ import {normalizeTextStyles} from '#/alf/typography'
import {Portal} from '#/components/Portal'
import {Text} from '../../util/text/Text'
import {createSuggestion} from './web/Autocomplete'
import {Emoji} from './web/EmojiPicker.web'
import {type Emoji} from './web/EmojiPicker'
import {LinkDecorator} from './web/LinkDecorator'
import {TagDecorator} from './web/TagDecorator'
@@ -0,0 +1,37 @@
export type Emoji = {
aliases?: string[]
emoticons: string[]
id: string
keywords: string[]
name: string
native: string
shortcodes?: string
unified: string
}
export interface EmojiPickerPosition {
top: number
left: number
right: number
bottom: number
nextFocusRef: React.MutableRefObject<HTMLElement> | null
}
export interface EmojiPickerState {
isOpen: boolean
pos: EmojiPickerPosition
}
interface IProps {
state: EmojiPickerState
close: () => void
/**
* If `true`, overrides position and ensures picker is pinned to the top of
* the target element.
*/
pinToTop?: boolean
}
export function EmojiPicker(_opts: IProps) {
return null
}
@@ -3,8 +3,7 @@ import {Pressable, useWindowDimensions, View} from 'react-native'
import Picker from '@emoji-mart/react'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {DismissableLayer} from '@radix-ui/react-dismissable-layer'
import {FocusScope} from '@radix-ui/react-focus-scope'
import {DismissableLayer, FocusScope} from 'radix-ui/internal'
import {textInputWebEmitter} from '#/view/com/composer/text-input/textInputWebEmitter'
import {atoms as a, flatten} from '#/alf'
@@ -121,7 +120,7 @@ export function EmojiPicker({state, close, pinToTop}: IProps) {
return (
<Portal>
<FocusScope
<FocusScope.FocusScope
loop
trapped
onUnmountAutoFocus={e => {
@@ -154,7 +153,7 @@ export function EmojiPicker({state, close, pinToTop}: IProps) {
},
])}>
<View style={[{position: 'absolute'}, position]}>
<DismissableLayer
<DismissableLayer.DismissableLayer
onFocusOutside={evt => evt.preventDefault()}
onDismiss={close}>
<Picker
@@ -164,7 +163,7 @@ export function EmojiPicker({state, close, pinToTop}: IProps) {
onEmojiSelect={onInsert}
autoFocus={true}
/>
</DismissableLayer>
</DismissableLayer.DismissableLayer>
</View>
</View>
@@ -175,7 +174,7 @@ export function EmojiPicker({state, close, pinToTop}: IProps) {
onPress={close}
style={[a.fixed, a.inset_0]}
/>
</FocusScope>
</FocusScope.FocusScope>
</Portal>
)
}
+10 -4
View File
@@ -1,9 +1,15 @@
import React from 'react'
import {Pressable, StyleSheet, Text, View, ViewStyle} from 'react-native'
import {IconProp} from '@fortawesome/fontawesome-svg-core'
import {
Pressable,
StyleSheet,
Text,
type View,
type ViewStyle,
} from 'react-native'
import {type IconProp} from '@fortawesome/fontawesome-svg-core'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
import {MenuItemCommonProps} from 'zeego/lib/typescript/menu'
import {DropdownMenu} from 'radix-ui'
import {type MenuItemCommonProps} from 'zeego/lib/typescript/menu'
import {HITSLOP_10} from '#/lib/constants'
import {usePalette} from '#/lib/hooks/usePalette'
+10 -12
View File
@@ -1,18 +1,16 @@
import React from 'react'
import {StyleSheet, View} from 'react-native'
import {DismissableLayer} from '@radix-ui/react-dismissable-layer'
import {useFocusGuards} from '@radix-ui/react-focus-guards'
import {FocusScope} from '@radix-ui/react-focus-scope'
import {DismissableLayer, FocusGuards, FocusScope} from 'radix-ui/internal'
import {RemoveScrollBar} from 'react-remove-scroll-bar'
import {useA11y} from '#/state/a11y'
import {useModals} from '#/state/modals'
import {ComposerOpts, useComposerState} from '#/state/shell/composer'
import {type ComposerOpts, useComposerState} from '#/state/shell/composer'
import {
EmojiPicker,
EmojiPickerPosition,
EmojiPickerState,
} from '#/view/com/composer/text-input/web/EmojiPicker.web'
type EmojiPickerPosition,
type EmojiPickerState,
} from '#/view/com/composer/text-input/web/EmojiPicker'
import {atoms as a, flatten, useBreakpoints, useTheme} from '#/alf'
import {ComposePost, useComposerCancelRef} from '../com/composer/Composer'
@@ -66,11 +64,11 @@ function Inner({state}: {state: ComposerOpts}) {
}))
}, [])
useFocusGuards()
FocusGuards.useFocusGuards()
return (
<FocusScope loop trapped asChild>
<DismissableLayer
<FocusScope.FocusScope loop trapped asChild>
<DismissableLayer.DismissableLayer
role="dialog"
aria-modal
style={flatten([
@@ -114,8 +112,8 @@ function Inner({state}: {state: ComposerOpts}) {
/>
</View>
<EmojiPicker state={pickerState} close={onClosePicker} />
</DismissableLayer>
</FocusScope>
</DismissableLayer.DismissableLayer>
</FocusScope.FocusScope>
)
}