Autosize dialog, handle max height, Dialog.ScrolLView not working
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import React, {useImperativeHandle} from 'react'
|
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 BottomSheet, {BottomSheetBackdrop} from '@gorhom/bottom-sheet'
|
||||||
|
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||||
|
|
||||||
import {useTheme, atoms as a} from '#/alf'
|
import {useTheme, atoms as a} from '#/alf'
|
||||||
import {Portal} from '#/components/Portal'
|
import {Portal} from '#/components/Portal'
|
||||||
@@ -12,6 +13,13 @@ 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'
|
||||||
|
|
||||||
@@ -21,8 +29,12 @@ export function Outer({
|
|||||||
onClose,
|
onClose,
|
||||||
nativeOptions,
|
nativeOptions,
|
||||||
}: React.PropsWithChildren<DialogOuterProps>) {
|
}: React.PropsWithChildren<DialogOuterProps>) {
|
||||||
|
const insets = useSafeAreaInsets()
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const sheet = React.useRef<BottomSheet>(null)
|
const sheet = React.useRef<BottomSheet>(null)
|
||||||
|
const [defaultSnapPoints, setDefaultSnapPoints] = React.useState<
|
||||||
|
string | number
|
||||||
|
>('25%')
|
||||||
|
|
||||||
const open = React.useCallback<DialogControlProps['open']>((i = 0) => {
|
const open = React.useCallback<DialogControlProps['open']>((i = 0) => {
|
||||||
sheet.current?.snapToIndex(i)
|
sheet.current?.snapToIndex(i)
|
||||||
@@ -33,6 +45,15 @@ export function Outer({
|
|||||||
onClose?.()
|
onClose?.()
|
||||||
}, [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(
|
useImperativeHandle(
|
||||||
control.ref,
|
control.ref,
|
||||||
() => ({
|
() => ({
|
||||||
@@ -47,9 +68,9 @@ export function Outer({
|
|||||||
return (
|
return (
|
||||||
<Portal>
|
<Portal>
|
||||||
<BottomSheet
|
<BottomSheet
|
||||||
snapPoints={['90%']}
|
snapPoints={[defaultSnapPoints]}
|
||||||
enablePanDownToClose
|
enablePanDownToClose
|
||||||
keyboardBehavior="extend"
|
keyboardBehavior="interactive"
|
||||||
android_keyboardInputMode="adjustResize"
|
android_keyboardInputMode="adjustResize"
|
||||||
{...(nativeOptions?.sheet || {})}
|
{...(nativeOptions?.sheet || {})}
|
||||||
ref={sheet}
|
ref={sheet}
|
||||||
@@ -78,7 +99,7 @@ export function Outer({
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
{children}
|
<View onLayout={measureDefaultSnapPoint}>{children}</View>
|
||||||
</Context.Provider>
|
</Context.Provider>
|
||||||
</BottomSheet>
|
</BottomSheet>
|
||||||
</Portal>
|
</Portal>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ 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'
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {View, PressableProps, LayoutChangeEvent} from 'react-native'
|
import {View, PressableProps} from 'react-native'
|
||||||
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
|
||||||
|
|
||||||
import {useTheme, atoms as a} from '#/alf'
|
import {useTheme, atoms as a} from '#/alf'
|
||||||
import {H4, P} from '#/components/Typography'
|
import {H4, P} from '#/components/Typography'
|
||||||
@@ -24,43 +23,24 @@ export function Outer({
|
|||||||
}: React.PropsWithChildren<{
|
}: React.PropsWithChildren<{
|
||||||
control: Dialog.DialogOuterProps['control']
|
control: Dialog.DialogOuterProps['control']
|
||||||
}>) {
|
}>) {
|
||||||
const insets = useSafeAreaInsets()
|
|
||||||
const titleId = React.useId()
|
const titleId = React.useId()
|
||||||
const descriptionId = React.useId()
|
const descriptionId = React.useId()
|
||||||
const [defaultSnapPoints, setDefaultSnapPoints] = React.useState<
|
|
||||||
string | number
|
|
||||||
>('25%')
|
|
||||||
|
|
||||||
const context = React.useMemo(
|
const context = React.useMemo(
|
||||||
() => ({titleId, descriptionId}),
|
() => ({titleId, descriptionId}),
|
||||||
[titleId, descriptionId],
|
[titleId, descriptionId],
|
||||||
)
|
)
|
||||||
|
|
||||||
const measureDefaultSnapPoint = React.useCallback(
|
|
||||||
(e: LayoutChangeEvent) => {
|
|
||||||
setDefaultSnapPoints(e.nativeEvent.layout.height + insets.bottom + 50)
|
|
||||||
},
|
|
||||||
[insets, setDefaultSnapPoints],
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog.Outer
|
<Dialog.Outer control={control}>
|
||||||
control={control}
|
|
||||||
nativeOptions={{
|
|
||||||
sheet: {
|
|
||||||
snapPoints: [defaultSnapPoints],
|
|
||||||
},
|
|
||||||
}}>
|
|
||||||
<Context.Provider value={context}>
|
<Context.Provider value={context}>
|
||||||
<View onLayout={measureDefaultSnapPoint}>
|
<Dialog.Inner
|
||||||
<Dialog.Inner
|
accessibilityLabelledBy={titleId}
|
||||||
accessibilityLabelledBy={titleId}
|
accessibilityDescribedBy={descriptionId}
|
||||||
accessibilityDescribedBy={descriptionId}
|
style={{width: 'auto', maxWidth: 400}}>
|
||||||
style={{width: 'auto', maxWidth: 400}}>
|
<Dialog.Handle />
|
||||||
<Dialog.Handle />
|
{children}
|
||||||
{children}
|
</Dialog.Inner>
|
||||||
</Dialog.Inner>
|
|
||||||
</View>
|
|
||||||
</Context.Provider>
|
</Context.Provider>
|
||||||
</Dialog.Outer>
|
</Dialog.Outer>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ export function Dialogs() {
|
|||||||
accessibilityLabelledBy="dialog-title"
|
accessibilityLabelledBy="dialog-title"
|
||||||
accessibilityDescribedBy="dialog-description">
|
accessibilityDescribedBy="dialog-description">
|
||||||
<Dialog.Handle />
|
<Dialog.Handle />
|
||||||
|
|
||||||
<View style={[a.gap_md]}>
|
<View style={[a.gap_md]}>
|
||||||
<H3 nativeID="dialog-title">Dialog</H3>
|
<H3 nativeID="dialog-title">Dialog</H3>
|
||||||
<P nativeID="dialog-description">Description</P>
|
<P nativeID="dialog-description">Description</P>
|
||||||
|
|||||||
Reference in New Issue
Block a user