Autosize dialog, handle max height, Dialog.ScrolLView not working

This commit is contained in:
Eric Bailey
2024-01-14 11:14:13 -06:00
parent cb1bfe0e6f
commit 4f71e4ee7d
4 changed files with 36 additions and 33 deletions
+25 -4
View File
@@ -1,6 +1,7 @@
import React, {useImperativeHandle} from 'react'
import {View, Dimensions} from 'react-native'
import {View, Dimensions, LayoutChangeEvent} from 'react-native'
import BottomSheet, {BottomSheetBackdrop} from '@gorhom/bottom-sheet'
import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {useTheme, atoms as a} from '#/alf'
import {Portal} from '#/components/Portal'
@@ -12,6 +13,13 @@ import {
} from '#/components/Dialog/types'
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 * from '#/components/Dialog/types'
@@ -21,8 +29,12 @@ export function Outer({
onClose,
nativeOptions,
}: React.PropsWithChildren<DialogOuterProps>) {
const insets = useSafeAreaInsets()
const t = useTheme()
const sheet = React.useRef<BottomSheet>(null)
const [defaultSnapPoints, setDefaultSnapPoints] = React.useState<
string | number
>('25%')
const open = React.useCallback<DialogControlProps['open']>((i = 0) => {
sheet.current?.snapToIndex(i)
@@ -33,6 +45,15 @@ export function Outer({
onClose?.()
}, [onClose])
const measureDefaultSnapPoint = React.useCallback(
(e: LayoutChangeEvent) => {
const min = e.nativeEvent.layout.height + insets.bottom + 40
const max = Dimensions.get('window').height - insets.top - 40
setDefaultSnapPoints(min < max ? min : max)
},
[insets, setDefaultSnapPoints],
)
useImperativeHandle(
control.ref,
() => ({
@@ -47,9 +68,9 @@ export function Outer({
return (
<Portal>
<BottomSheet
snapPoints={['90%']}
snapPoints={[defaultSnapPoints]}
enablePanDownToClose
keyboardBehavior="extend"
keyboardBehavior="interactive"
android_keyboardInputMode="adjustResize"
{...(nativeOptions?.sheet || {})}
ref={sheet}
@@ -78,7 +99,7 @@ export function Outer({
},
]}
/>
{children}
<View onLayout={measureDefaultSnapPoint}>{children}</View>
</Context.Provider>
</BottomSheet>
</Portal>
+1
View File
@@ -11,6 +11,7 @@ import {Button} from '#/components/Button'
import {DialogOuterProps, DialogInnerProps} from '#/components/Dialog/types'
import {Context, useDialogContext} from '#/components/Dialog/context'
export {ScrollView, TextInput} from 'react-native'
export {useDialogControl, useDialogContext} from '#/components/Dialog/context'
export * from '#/components/Dialog/types'
+9 -29
View File
@@ -1,6 +1,5 @@
import React from 'react'
import {View, PressableProps, LayoutChangeEvent} from 'react-native'
import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {View, PressableProps} from 'react-native'
import {useTheme, atoms as a} from '#/alf'
import {H4, P} from '#/components/Typography'
@@ -24,43 +23,24 @@ export function Outer({
}: React.PropsWithChildren<{
control: Dialog.DialogOuterProps['control']
}>) {
const insets = useSafeAreaInsets()
const titleId = React.useId()
const descriptionId = React.useId()
const [defaultSnapPoints, setDefaultSnapPoints] = React.useState<
string | number
>('25%')
const context = React.useMemo(
() => ({titleId, descriptionId}),
[titleId, descriptionId],
)
const measureDefaultSnapPoint = React.useCallback(
(e: LayoutChangeEvent) => {
setDefaultSnapPoints(e.nativeEvent.layout.height + insets.bottom + 50)
},
[insets, setDefaultSnapPoints],
)
return (
<Dialog.Outer
control={control}
nativeOptions={{
sheet: {
snapPoints: [defaultSnapPoints],
},
}}>
<Dialog.Outer control={control}>
<Context.Provider value={context}>
<View onLayout={measureDefaultSnapPoint}>
<Dialog.Inner
accessibilityLabelledBy={titleId}
accessibilityDescribedBy={descriptionId}
style={{width: 'auto', maxWidth: 400}}>
<Dialog.Handle />
{children}
</Dialog.Inner>
</View>
<Dialog.Inner
accessibilityLabelledBy={titleId}
accessibilityDescribedBy={descriptionId}
style={{width: 'auto', maxWidth: 400}}>
<Dialog.Handle />
{children}
</Dialog.Inner>
</Context.Provider>
</Dialog.Outer>
)
+1
View File
@@ -50,6 +50,7 @@ export function Dialogs() {
accessibilityLabelledBy="dialog-title"
accessibilityDescribedBy="dialog-description">
<Dialog.Handle />
<View style={[a.gap_md]}>
<H3 nativeID="dialog-title">Dialog</H3>
<P nativeID="dialog-description">Description</P>