diff options
author | Samuel Newman <mozzius@protonmail.com> | 2024-10-08 20:00:49 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-08 20:00:49 +0300 |
commit | fc82d2f6d5e8a93f0e7ce4861c5205c8a4b49c30 (patch) | |
tree | 51e618db283d28ef241f0e6f2f6180004e6cb6e7 /src/components | |
parent | efcf8a6ae59d9767bc2289af927a2e12bc39a054 (diff) | |
download | voidsky-fc82d2f6d5e8a93f0e7ce4861c5205c8a4b49c30.tar.zst |
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>
Diffstat (limited to 'src/components')
-rw-r--r-- | src/components/Dialog/index.web.tsx | 36 | ||||
-rw-r--r-- | src/components/Menu/index.tsx | 9 | ||||
-rw-r--r-- | src/components/Prompt.tsx | 9 | ||||
-rw-r--r-- | src/components/dialogs/GifSelect.tsx | 6 |
4 files changed, 33 insertions, 27 deletions
diff --git a/src/components/Dialog/index.web.tsx b/src/components/Dialog/index.web.tsx index 7b9cfb693..1a20311d3 100644 --- a/src/components/Dialog/index.web.tsx +++ b/src/components/Dialog/index.web.tsx @@ -10,7 +10,9 @@ import { import Animated, {FadeIn, FadeInDown} from 'react-native-reanimated' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {FocusScope} from '@tamagui/focus-scope' +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 {logger} from '#/logger' import {useDialogStateControlContext} from '#/state/dialogs' @@ -31,6 +33,7 @@ export * from '#/components/Dialog/utils' export {Input} from '#/components/forms/TextField' const stopPropagation = (e: any) => e.stopPropagation() +const preventDefault = (e: any) => e.preventDefault() export function Outer({ children, @@ -85,21 +88,6 @@ export function Outer({ [close, open], ) - React.useEffect(() => { - if (!isOpen) return - - function handler(e: KeyboardEvent) { - if (e.key === 'Escape') { - e.stopPropagation() - close() - } - } - - document.addEventListener('keydown', handler) - - return () => document.removeEventListener('keydown', handler) - }, [close, isOpen]) - const context = React.useMemo( () => ({ close, @@ -168,9 +156,11 @@ export function Inner({ accessibilityDescribedBy, }: DialogInnerProps) { const t = useTheme() + const {close} = React.useContext(Context) const {gtMobile} = useBreakpoints() + useFocusGuards() return ( - <FocusScope loop enabled trapped> + <FocusScope loop asChild trapped> <Animated.View role="dialog" aria-role="dialog" @@ -183,7 +173,7 @@ export function Inner({ onTouchEnd={stopPropagation} entering={FadeInDown.duration(100)} // exiting={FadeOut.duration(100)} - style={[ + style={flatten([ a.relative, a.rounded_md, a.w_full, @@ -198,8 +188,14 @@ export function Inner({ shadowRadius: 30, }, flatten(style), - ]}> - {children} + ])}> + <DismissableLayer + onInteractOutside={preventDefault} + onFocusOutside={preventDefault} + onDismiss={close} + style={{display: 'flex', flexDirection: 'column'}}> + {children} + </DismissableLayer> </Animated.View> </FocusScope> ) diff --git a/src/components/Menu/index.tsx b/src/components/Menu/index.tsx index a22f43cf8..12cf1866e 100644 --- a/src/components/Menu/index.tsx +++ b/src/components/Menu/index.tsx @@ -18,6 +18,7 @@ import { ItemTextProps, TriggerProps, } from '#/components/Menu/types' +import {PortalComponent} from '#/components/Portal' import {Text} from '#/components/Typography' export { @@ -77,9 +78,11 @@ export function Trigger({children, label}: TriggerProps) { export function Outer({ children, showCancel, + Portal, }: React.PropsWithChildren<{ showCancel?: boolean style?: StyleProp<ViewStyle> + Portal?: PortalComponent }>) { const context = React.useContext(Context) const {_} = useLingui() @@ -87,15 +90,15 @@ export function Outer({ return ( <Dialog.Outer control={context.control} - nativeOptions={{preventExpansion: true}}> + nativeOptions={{preventExpansion: true}} + Portal={Portal}> <Dialog.Handle /> {/* Re-wrap with context since Dialogs are portal-ed to root */} <Context.Provider value={context}> - <Dialog.ScrollableInner label={_(msg`Menu`)} style={[a.pt_sm]}> + <Dialog.ScrollableInner label={_(msg`Menu`)} style={[a.py_sm]}> <View style={[a.gap_lg]}> {children} {isNative && showCancel && <Cancel />} - <View style={[{height: a.pb_lg.paddingBottom}]} /> </View> </Dialog.ScrollableInner> </Context.Provider> diff --git a/src/components/Prompt.tsx b/src/components/Prompt.tsx index fc6919af8..c47f0d64a 100644 --- a/src/components/Prompt.tsx +++ b/src/components/Prompt.tsx @@ -8,6 +8,7 @@ import {Button, ButtonColor, ButtonText} from '#/components/Button' import * as Dialog from '#/components/Dialog' import {PortalComponent} from '#/components/Portal' import {Text} from '#/components/Typography' +import {BottomSheetViewProps} from '../../modules/bottom-sheet' export { type DialogControlProps as PromptControlProps, @@ -27,10 +28,12 @@ export function Outer({ control, testID, Portal, + nativeOptions, }: React.PropsWithChildren<{ control: Dialog.DialogControlProps testID?: string Portal?: PortalComponent + nativeOptions?: Omit<BottomSheetViewProps, 'children'> }>) { const {gtMobile} = useBreakpoints() const titleId = React.useId() @@ -42,7 +45,11 @@ export function Outer({ ) return ( - <Dialog.Outer control={control} testID={testID} Portal={Portal}> + <Dialog.Outer + control={control} + testID={testID} + Portal={Portal} + nativeOptions={{preventExpansion: true, ...nativeOptions}}> <Dialog.Handle /> <Context.Provider value={context}> <Dialog.ScrollableInner diff --git a/src/components/dialogs/GifSelect.tsx b/src/components/dialogs/GifSelect.tsx index 6023b5808..c0ed202da 100644 --- a/src/components/dialogs/GifSelect.tsx +++ b/src/components/dialogs/GifSelect.tsx @@ -23,14 +23,14 @@ import {ErrorScreen} from '#/view/com/util/error/ErrorScreen' import {ErrorBoundary} from '#/view/com/util/ErrorBoundary' import {ListMethods} from '#/view/com/util/List' import {atoms as a, ios, native, useBreakpoints, useTheme} from '#/alf' +import {Button, ButtonIcon, ButtonText} from '#/components/Button' import * as Dialog from '#/components/Dialog' import * as TextField from '#/components/forms/TextField' import {useThrottledValue} from '#/components/hooks/useThrottledValue' import {ArrowLeft_Stroke2_Corner0_Rounded as Arrow} from '#/components/icons/Arrow' import {MagnifyingGlass2_Stroke2_Corner0_Rounded as Search} from '#/components/icons/MagnifyingGlass2' -import {Button, ButtonIcon, ButtonText} from '../Button' -import {ListFooter, ListMaybePlaceholder} from '../Lists' -import {PortalComponent} from '../Portal' +import {ListFooter, ListMaybePlaceholder} from '#/components/Lists' +import {PortalComponent} from '#/components/Portal' export function GifSelectDialog({ controlRef, |