Autosize dialog, handle max height, Dialog.ScrolLView not working
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user