Scrollable dialogs
This commit is contained in:
+1
-5
@@ -41,10 +41,7 @@ import {
|
|||||||
import {Provider as UnreadNotifsProvider} from 'state/queries/notifications/unread'
|
import {Provider as UnreadNotifsProvider} from 'state/queries/notifications/unread'
|
||||||
import * as persisted from '#/state/persisted'
|
import * as persisted from '#/state/persisted'
|
||||||
import {Splash} from '#/Splash'
|
import {Splash} from '#/Splash'
|
||||||
import {
|
import {Provider as PortalProvider} from '#/components/Portal'
|
||||||
Provider as PortalProvider,
|
|
||||||
Outlet as PortalOutlet,
|
|
||||||
} from '#/components/Portal'
|
|
||||||
|
|
||||||
SplashScreen.preventAutoHideAsync()
|
SplashScreen.preventAutoHideAsync()
|
||||||
|
|
||||||
@@ -80,7 +77,6 @@ function InnerApp() {
|
|||||||
<GestureHandlerRootView style={s.h100pct}>
|
<GestureHandlerRootView style={s.h100pct}>
|
||||||
<TestCtrls />
|
<TestCtrls />
|
||||||
<Shell />
|
<Shell />
|
||||||
<PortalOutlet />
|
|
||||||
</GestureHandlerRootView>
|
</GestureHandlerRootView>
|
||||||
</RootSiblingParent>
|
</RootSiblingParent>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
|
|||||||
+1
-5
@@ -30,10 +30,7 @@ import {
|
|||||||
} from 'state/session'
|
} from 'state/session'
|
||||||
import {Provider as UnreadNotifsProvider} from 'state/queries/notifications/unread'
|
import {Provider as UnreadNotifsProvider} from 'state/queries/notifications/unread'
|
||||||
import * as persisted from '#/state/persisted'
|
import * as persisted from '#/state/persisted'
|
||||||
import {
|
import {Provider as PortalProvider} from '#/components/Portal'
|
||||||
Provider as PortalProvider,
|
|
||||||
Outlet as PortalOutlet,
|
|
||||||
} from '#/components/Portal'
|
|
||||||
|
|
||||||
function InnerApp() {
|
function InnerApp() {
|
||||||
const {isInitialLoad, currentAccount} = useSession()
|
const {isInitialLoad, currentAccount} = useSession()
|
||||||
@@ -62,7 +59,6 @@ function InnerApp() {
|
|||||||
<RootSiblingParent>
|
<RootSiblingParent>
|
||||||
<SafeAreaProvider>
|
<SafeAreaProvider>
|
||||||
<Shell />
|
<Shell />
|
||||||
<PortalOutlet />
|
|
||||||
</SafeAreaProvider>
|
</SafeAreaProvider>
|
||||||
</RootSiblingParent>
|
</RootSiblingParent>
|
||||||
<ToastContainer />
|
<ToastContainer />
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React, {useImperativeHandle} from 'react'
|
|||||||
import {View, Dimensions} from 'react-native'
|
import {View, Dimensions} from 'react-native'
|
||||||
import BottomSheet, {
|
import BottomSheet, {
|
||||||
BottomSheetBackdrop,
|
BottomSheetBackdrop,
|
||||||
|
BottomSheetScrollView,
|
||||||
BottomSheetView,
|
BottomSheetView,
|
||||||
} from '@gorhom/bottom-sheet'
|
} from '@gorhom/bottom-sheet'
|
||||||
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||||
@@ -16,13 +17,6 @@ import {
|
|||||||
} from '#/components/Dialog/types'
|
} from '#/components/Dialog/types'
|
||||||
import {Context} from '#/components/Dialog/context'
|
import {Context} from '#/components/Dialog/context'
|
||||||
|
|
||||||
/**
|
|
||||||
* Exports
|
|
||||||
*/
|
|
||||||
export {
|
|
||||||
BottomSheetScrollView as ScrollView,
|
|
||||||
BottomSheetTextInput as TextInput,
|
|
||||||
} from '@gorhom/bottom-sheet'
|
|
||||||
export {useDialogControl, useDialogContext} from '#/components/Dialog/context'
|
export {useDialogControl, useDialogContext} from '#/components/Dialog/context'
|
||||||
export * from '#/components/Dialog/types'
|
export * from '#/components/Dialog/types'
|
||||||
|
|
||||||
@@ -34,6 +28,8 @@ export function Outer({
|
|||||||
}: React.PropsWithChildren<DialogOuterProps>) {
|
}: React.PropsWithChildren<DialogOuterProps>) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const sheet = React.useRef<BottomSheet>(null)
|
const sheet = React.useRef<BottomSheet>(null)
|
||||||
|
const sheetOptions = nativeOptions?.sheet || {}
|
||||||
|
const hasSnapPoints = !!sheetOptions.snapPoints
|
||||||
|
|
||||||
const open = React.useCallback<DialogControlProps['open']>((i = 0) => {
|
const open = React.useCallback<DialogControlProps['open']>((i = 0) => {
|
||||||
sheet.current?.snapToIndex(i)
|
sheet.current?.snapToIndex(i)
|
||||||
@@ -58,15 +54,15 @@ export function Outer({
|
|||||||
return (
|
return (
|
||||||
<Portal>
|
<Portal>
|
||||||
<BottomSheet
|
<BottomSheet
|
||||||
enableDynamicSizing
|
enableDynamicSizing={!hasSnapPoints}
|
||||||
enablePanDownToClose
|
enablePanDownToClose
|
||||||
keyboardBehavior="interactive"
|
keyboardBehavior="interactive"
|
||||||
android_keyboardInputMode="adjustResize"
|
android_keyboardInputMode="adjustResize"
|
||||||
keyboardBlurBehavior="restore"
|
keyboardBlurBehavior="restore"
|
||||||
{...(nativeOptions?.sheet || {})}
|
{...sheetOptions}
|
||||||
ref={sheet}
|
ref={sheet}
|
||||||
index={-1}
|
index={-1}
|
||||||
backgroundStyle={{backgroundColor: 'transparent'}}
|
backgroundStyle={{backgroundColor: t.atoms.bg.backgroundColor}}
|
||||||
backdropComponent={props => (
|
backdropComponent={props => (
|
||||||
<BottomSheetBackdrop
|
<BottomSheetBackdrop
|
||||||
appearsOnIndex={0}
|
appearsOnIndex={0}
|
||||||
@@ -77,23 +73,21 @@ export function Outer({
|
|||||||
handleIndicatorStyle={{backgroundColor: t.palette.primary_500}}
|
handleIndicatorStyle={{backgroundColor: t.palette.primary_500}}
|
||||||
handleStyle={{display: 'none'}}
|
handleStyle={{display: 'none'}}
|
||||||
onClose={onClose}>
|
onClose={onClose}>
|
||||||
<BottomSheetView>
|
<Context.Provider value={context}>
|
||||||
<Context.Provider value={context}>
|
<View
|
||||||
<View
|
style={[
|
||||||
style={[
|
a.absolute,
|
||||||
a.absolute,
|
a.inset_0,
|
||||||
a.inset_0,
|
t.atoms.bg,
|
||||||
t.atoms.bg,
|
{
|
||||||
{
|
borderTopLeftRadius: 40,
|
||||||
borderTopLeftRadius: 40,
|
borderTopRightRadius: 40,
|
||||||
borderTopRightRadius: 40,
|
height: Dimensions.get('window').height * 2,
|
||||||
height: Dimensions.get('window').height * 2,
|
},
|
||||||
},
|
]}
|
||||||
]}
|
/>
|
||||||
/>
|
{children}
|
||||||
{children}
|
</Context.Provider>
|
||||||
</Context.Provider>
|
|
||||||
</BottomSheetView>
|
|
||||||
</BottomSheet>
|
</BottomSheet>
|
||||||
</Portal>
|
</Portal>
|
||||||
)
|
)
|
||||||
@@ -103,7 +97,7 @@ export function Outer({
|
|||||||
export function Inner(props: DialogInnerProps) {
|
export function Inner(props: DialogInnerProps) {
|
||||||
const insets = useSafeAreaInsets()
|
const insets = useSafeAreaInsets()
|
||||||
return (
|
return (
|
||||||
<View
|
<BottomSheetView
|
||||||
style={[
|
style={[
|
||||||
a.p_lg,
|
a.p_lg,
|
||||||
a.pt_3xl,
|
a.pt_3xl,
|
||||||
@@ -114,7 +108,26 @@ export function Inner(props: DialogInnerProps) {
|
|||||||
},
|
},
|
||||||
]}>
|
]}>
|
||||||
{props.children}
|
{props.children}
|
||||||
</View>
|
</BottomSheetView>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ScrollableInner(props: DialogInnerProps) {
|
||||||
|
const insets = useSafeAreaInsets()
|
||||||
|
return (
|
||||||
|
<BottomSheetScrollView
|
||||||
|
style={[
|
||||||
|
a.flex_1, // main diff is this
|
||||||
|
a.p_lg,
|
||||||
|
a.pt_3xl,
|
||||||
|
{
|
||||||
|
borderTopLeftRadius: 40,
|
||||||
|
borderTopRightRadius: 40,
|
||||||
|
paddingBottom: insets.bottom + a.pb_5xl.paddingBottom,
|
||||||
|
},
|
||||||
|
]}>
|
||||||
|
{props.children}
|
||||||
|
</BottomSheetScrollView>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,12 +139,13 @@ export function Handle() {
|
|||||||
a.absolute,
|
a.absolute,
|
||||||
a.rounded_sm,
|
a.rounded_sm,
|
||||||
a.z_10,
|
a.z_10,
|
||||||
t.atoms.bg_contrast_200,
|
|
||||||
{
|
{
|
||||||
top: 12,
|
top: a.pt_lg.paddingTop,
|
||||||
width: 50,
|
width: 35,
|
||||||
height: 6,
|
height: 4,
|
||||||
alignSelf: 'center',
|
alignSelf: 'center',
|
||||||
|
backgroundColor: t.palette.contrast_900,
|
||||||
|
opacity: 0.5,
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import {Button} from '#/components/Button'
|
|||||||
import {DialogOuterProps, DialogInnerProps} from '#/components/Dialog/types'
|
import {DialogOuterProps, DialogInnerProps} from '#/components/Dialog/types'
|
||||||
import {Context, useDialogContext} from '#/components/Dialog/context'
|
import {Context, useDialogContext} from '#/components/Dialog/context'
|
||||||
|
|
||||||
export {ScrollView, TextInput} from 'react-native'
|
|
||||||
export {useDialogControl, useDialogContext} from '#/components/Dialog/context'
|
export {useDialogControl, useDialogContext} from '#/components/Dialog/context'
|
||||||
export * from '#/components/Dialog/types'
|
export * from '#/components/Dialog/types'
|
||||||
|
|
||||||
@@ -91,7 +90,7 @@ export function Outer({
|
|||||||
style={[
|
style={[
|
||||||
web(a.fixed),
|
web(a.fixed),
|
||||||
a.inset_0,
|
a.inset_0,
|
||||||
t.atoms.bg_contrast_300,
|
t.atoms.bg_contrast_100,
|
||||||
{opacity: 0.8},
|
{opacity: 0.8},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
@@ -145,7 +144,7 @@ export function Inner({
|
|||||||
a.border,
|
a.border,
|
||||||
gtMobile ? a.p_xl : a.p_lg,
|
gtMobile ? a.p_xl : a.p_lg,
|
||||||
t.atoms.bg,
|
t.atoms.bg,
|
||||||
{maxWidth: 600, borderColor: t.palette.contrast_300},
|
{maxWidth: 600, borderColor: t.palette.contrast_200},
|
||||||
...(Array.isArray(style) ? style : [style || {}]),
|
...(Array.isArray(style) ? style : [style || {}]),
|
||||||
]}>
|
]}>
|
||||||
{children}
|
{children}
|
||||||
@@ -154,6 +153,8 @@ export function Inner({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const ScrollableInner = Inner
|
||||||
|
|
||||||
export function Handle() {
|
export function Handle() {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,11 +34,12 @@ export function Outer({
|
|||||||
return (
|
return (
|
||||||
<Dialog.Outer control={control}>
|
<Dialog.Outer control={control}>
|
||||||
<Context.Provider value={context}>
|
<Context.Provider value={context}>
|
||||||
|
<Dialog.Handle />
|
||||||
|
|
||||||
<Dialog.Inner
|
<Dialog.Inner
|
||||||
accessibilityLabelledBy={titleId}
|
accessibilityLabelledBy={titleId}
|
||||||
accessibilityDescribedBy={descriptionId}
|
accessibilityDescribedBy={descriptionId}
|
||||||
style={{width: 'auto', maxWidth: 400}}>
|
style={{width: 'auto', maxWidth: 400}}>
|
||||||
<Dialog.Handle />
|
|
||||||
{children}
|
{children}
|
||||||
</Dialog.Inner>
|
</Dialog.Inner>
|
||||||
</Context.Provider>
|
</Context.Provider>
|
||||||
|
|||||||
@@ -45,15 +45,18 @@ export function Dialogs() {
|
|||||||
</Prompt.Actions>
|
</Prompt.Actions>
|
||||||
</Prompt.Outer>
|
</Prompt.Outer>
|
||||||
|
|
||||||
<Dialog.Outer control={control}>
|
<Dialog.Outer
|
||||||
<Dialog.Inner
|
control={control}
|
||||||
|
nativeOptions={{sheet: {snapPoints: ['90%']}}}>
|
||||||
|
<Dialog.Handle />
|
||||||
|
|
||||||
|
<Dialog.ScrollableInner
|
||||||
accessibilityLabelledBy="dialog-title"
|
accessibilityLabelledBy="dialog-title"
|
||||||
accessibilityDescribedBy="dialog-description">
|
accessibilityDescribedBy="dialog-description">
|
||||||
<Dialog.Handle />
|
|
||||||
|
|
||||||
<View style={[a.relative, a.gap_md, a.w_full]}>
|
<View style={[a.relative, a.gap_md, a.w_full]}>
|
||||||
<H3 nativeID="dialog-title">Dialog</H3>
|
<H3 nativeID="dialog-title">Dialog</H3>
|
||||||
<P nativeID="dialog-description">Description</P>
|
<P nativeID="dialog-description">Description</P>
|
||||||
|
<View style={{height: 1000}} />
|
||||||
<View style={[a.flex_row, a.justify_end]}>
|
<View style={[a.flex_row, a.justify_end]}>
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
@@ -66,7 +69,7 @@ export function Dialogs() {
|
|||||||
</Button>
|
</Button>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</Dialog.Inner>
|
</Dialog.ScrollableInner>
|
||||||
</Dialog.Outer>
|
</Dialog.Outer>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import {isAndroid} from 'platform/detection'
|
|||||||
import {useSession} from '#/state/session'
|
import {useSession} from '#/state/session'
|
||||||
import {useCloseAnyActiveElement} from '#/state/util'
|
import {useCloseAnyActiveElement} from '#/state/util'
|
||||||
import * as notifications from 'lib/notifications/notifications'
|
import * as notifications from 'lib/notifications/notifications'
|
||||||
|
import {Outlet as PortalOutlet} from '#/components/Portal'
|
||||||
|
|
||||||
function ShellInner() {
|
function ShellInner() {
|
||||||
const isDrawerOpen = useIsDrawerOpen()
|
const isDrawerOpen = useIsDrawerOpen()
|
||||||
@@ -94,6 +95,7 @@ function ShellInner() {
|
|||||||
</View>
|
</View>
|
||||||
<Composer winHeight={winDim.height} />
|
<Composer winHeight={winDim.height} />
|
||||||
<ModalsContainer />
|
<ModalsContainer />
|
||||||
|
<PortalOutlet />
|
||||||
<Lightbox />
|
<Lightbox />
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {useAuxClick} from 'lib/hooks/useAuxClick'
|
|||||||
import {t} from '@lingui/macro'
|
import {t} from '@lingui/macro'
|
||||||
import {useIsDrawerOpen, useSetDrawerOpen} from '#/state/shell'
|
import {useIsDrawerOpen, useSetDrawerOpen} from '#/state/shell'
|
||||||
import {useCloseAllActiveElements} from '#/state/util'
|
import {useCloseAllActiveElements} from '#/state/util'
|
||||||
|
import {Outlet as PortalOutlet} from '#/components/Portal'
|
||||||
|
|
||||||
function ShellInner() {
|
function ShellInner() {
|
||||||
const isDrawerOpen = useIsDrawerOpen()
|
const isDrawerOpen = useIsDrawerOpen()
|
||||||
@@ -41,6 +42,7 @@ function ShellInner() {
|
|||||||
</View>
|
</View>
|
||||||
<Composer winHeight={0} />
|
<Composer winHeight={0} />
|
||||||
<ModalsContainer />
|
<ModalsContainer />
|
||||||
|
<PortalOutlet />
|
||||||
<Lightbox />
|
<Lightbox />
|
||||||
{!isDesktop && isDrawerOpen && (
|
{!isDesktop && isDrawerOpen && (
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
|
|||||||
Reference in New Issue
Block a user