From b52a742925cff4429885e94815d61f3f7cfb5a66 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Mon, 19 Feb 2024 18:18:13 -0600 Subject: Improve dialogs (#2933) * Improve dialogs * Remove comment, revert storybook * Hacky fix * Comments --- src/components/Dialog/index.tsx | 121 +++++++++++++++++++++++----------------- 1 file changed, 70 insertions(+), 51 deletions(-) (limited to 'src/components/Dialog/index.tsx') diff --git a/src/components/Dialog/index.tsx b/src/components/Dialog/index.tsx index 9132e68de..f30d24e6a 100644 --- a/src/components/Dialog/index.tsx +++ b/src/components/Dialog/index.tsx @@ -8,7 +8,7 @@ import BottomSheet, { } from '@gorhom/bottom-sheet' import {useSafeAreaInsets} from 'react-native-safe-area-context' -import {useTheme, atoms as a} from '#/alf' +import {useTheme, atoms as a, flatten} from '#/alf' import {Portal} from '#/components/Portal' import {createInput} from '#/components/forms/TextField' @@ -36,9 +36,23 @@ export function Outer({ const hasSnapPoints = !!sheetOptions.snapPoints const insets = useSafeAreaInsets() - const open = React.useCallback((i = 0) => { - sheet.current?.snapToIndex(i) - }, []) + /* + * Used to manage open/closed, but index is otherwise handled internally by `BottomSheet` + */ + const [openIndex, setOpenIndex] = React.useState(-1) + + /* + * `openIndex` is the index of the snap point to open the bottom sheet to. If >0, the bottom sheet is open. + */ + const isOpen = openIndex > -1 + + const open = React.useCallback( + ({index} = {}) => { + // can be set to any index of `snapPoints`, but `0` is the first i.e. "open" + setOpenIndex(index || 0) + }, + [setOpenIndex], + ) const close = React.useCallback(() => { sheet.current?.close() @@ -57,77 +71,80 @@ export function Outer({ (index: number) => { if (index === -1) { onClose?.() + setOpenIndex(-1) } }, - [onClose], + [onClose, setOpenIndex], ) const context = React.useMemo(() => ({close}), [close]) return ( - - ( - - )} - handleIndicatorStyle={{backgroundColor: t.palette.primary_500}} - handleStyle={{display: 'none'}} - onChange={onChange}> - - - {children} - - - + isOpen && ( + + ( + + )} + handleIndicatorStyle={{backgroundColor: t.palette.primary_500}} + handleStyle={{display: 'none'}} + onChange={onChange}> + + + {hasSnapPoints ? children : {children}} + + + + ) ) } -// TODO a11y props here, or is that handled by the sheet? -export function Inner(props: DialogInnerProps) { +export function Inner({children, style}: DialogInnerProps) { const insets = useSafeAreaInsets() return ( - {props.children} + {children} ) } -export function ScrollableInner(props: DialogInnerProps) { +export function ScrollableInner({children, style}: DialogInnerProps) { const insets = useSafeAreaInsets() return ( - {props.children} + {children} ) -- cgit 1.4.1 From 8a169dc6a14d422f65ea4afb5af7fe30efacf2bb Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Tue, 20 Feb 2024 10:04:07 -0600 Subject: Improve dialogs issue (#2941) * Fix collapse, update backdrop color * Remove test prop * Remove debug code --- src/components/Dialog/index.tsx | 4 +++- src/view/screens/Storybook/Dialogs.tsx | 43 ++++++++++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 6 deletions(-) (limited to 'src/components/Dialog/index.tsx') diff --git a/src/components/Dialog/index.tsx b/src/components/Dialog/index.tsx index f30d24e6a..529535051 100644 --- a/src/components/Dialog/index.tsx +++ b/src/components/Dialog/index.tsx @@ -90,6 +90,7 @@ export function Outer({ keyboardBlurBehavior="restore" topInset={insets.top} {...sheetOptions} + snapPoints={sheetOptions.snapPoints || ['100%']} ref={sheet} index={openIndex} backgroundStyle={{backgroundColor: 'transparent'}} @@ -99,6 +100,7 @@ export function Outer({ appearsOnIndex={0} disappearsOnIndex={-1} {...props} + style={[flatten(props.style), t.atoms.bg_contrast_300]} /> )} handleIndicatorStyle={{backgroundColor: t.palette.primary_500}} @@ -117,7 +119,7 @@ export function Outer({ }, ]} /> - {hasSnapPoints ? children : {children}} + {children} diff --git a/src/view/screens/Storybook/Dialogs.tsx b/src/view/screens/Storybook/Dialogs.tsx index a18b3c62f..821ac3c88 100644 --- a/src/view/screens/Storybook/Dialogs.tsx +++ b/src/view/screens/Storybook/Dialogs.tsx @@ -9,7 +9,8 @@ import * as Prompt from '#/components/Prompt' import {useDialogStateControlContext} from '#/state/dialogs' export function Dialogs() { - const control = Dialog.useDialogControl() + const scrollable = Dialog.useDialogControl() + const basic = Dialog.useDialogControl() const prompt = Prompt.usePromptControl() const {closeAllDialogs} = useDialogStateControlContext() @@ -20,8 +21,31 @@ export function Dialogs() { color="secondary" size="small" onPress={() => { - control.open() + scrollable.open() prompt.open() + basic.open() + }} + label="Open basic dialog"> + Open all dialogs + + + + + -- cgit 1.4.1 From f88b16525498584f81ea7f594a63623fc5dc7ce9 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Tue, 20 Feb 2024 18:20:59 -0600 Subject: Add optional close callback to Dialog (#2947) * Add optional close callback * No emitter --- src/components/Dialog/context.ts | 10 +++++++--- src/components/Dialog/index.tsx | 8 +++++++- src/components/Dialog/types.ts | 6 ++---- src/view/screens/Storybook/Dialogs.tsx | 6 +++++- 4 files changed, 21 insertions(+), 9 deletions(-) (limited to 'src/components/Dialog/index.tsx') diff --git a/src/components/Dialog/context.ts b/src/components/Dialog/context.ts index b28b9f5a2..f0c7c983a 100644 --- a/src/components/Dialog/context.ts +++ b/src/components/Dialog/context.ts @@ -1,7 +1,11 @@ import React from 'react' import {useDialogStateContext} from '#/state/dialogs' -import {DialogContextProps, DialogControlProps} from '#/components/Dialog/types' +import { + DialogContextProps, + DialogControlProps, + DialogOuterProps, +} from '#/components/Dialog/types' export const Context = React.createContext({ close: () => {}, @@ -11,7 +15,7 @@ export function useDialogContext() { return React.useContext(Context) } -export function useDialogControl() { +export function useDialogControl(): DialogOuterProps['control'] { const id = React.useId() const control = React.useRef({ open: () => {}, @@ -30,6 +34,6 @@ export function useDialogControl() { return { ref: control, open: () => control.current.open(), - close: () => control.current.close(), + close: cb => control.current.close(cb), } } diff --git a/src/components/Dialog/index.tsx b/src/components/Dialog/index.tsx index 529535051..27f43afd3 100644 --- a/src/components/Dialog/index.tsx +++ b/src/components/Dialog/index.tsx @@ -35,6 +35,7 @@ export function Outer({ const sheetOptions = nativeOptions?.sheet || {} const hasSnapPoints = !!sheetOptions.snapPoints const insets = useSafeAreaInsets() + const closeCallback = React.useRef<() => void>() /* * Used to manage open/closed, but index is otherwise handled internally by `BottomSheet` @@ -54,7 +55,10 @@ export function Outer({ [setOpenIndex], ) - const close = React.useCallback(() => { + const close = React.useCallback(cb => { + if (cb) { + closeCallback.current = cb + } sheet.current?.close() }, []) @@ -70,6 +74,8 @@ export function Outer({ const onChange = React.useCallback( (index: number) => { if (index === -1) { + closeCallback.current?.() + closeCallback.current = undefined onClose?.() setOpenIndex(-1) } diff --git a/src/components/Dialog/types.ts b/src/components/Dialog/types.ts index 00178926a..75ba825ac 100644 --- a/src/components/Dialog/types.ts +++ b/src/components/Dialog/types.ts @@ -22,15 +22,13 @@ export type DialogControlOpenOptions = { export type DialogControlProps = { open: (options?: DialogControlOpenOptions) => void - close: () => void + close: (callback?: () => void) => void } export type DialogOuterProps = { control: { ref: React.RefObject - open: (index?: number) => void - close: () => void - } + } & DialogControlProps onClose?: () => void nativeOptions?: { sheet?: Omit diff --git a/src/view/screens/Storybook/Dialogs.tsx b/src/view/screens/Storybook/Dialogs.tsx index 821ac3c88..09be124db 100644 --- a/src/view/screens/Storybook/Dialogs.tsx +++ b/src/view/screens/Storybook/Dialogs.tsx @@ -110,7 +110,11 @@ export function Dialogs() { variant="outline" color="primary" size="small" - onPress={() => scrollable.close()} + onPress={() => + scrollable.close(() => { + console.log('CLOSED') + }) + } label="Open basic dialog"> Close dialog -- cgit 1.4.1