Add closeAllDialogs control

This commit is contained in:
Eric Bailey
2024-01-18 15:45:37 -06:00
parent 6d3f19c695
commit 83c2b20c39
6 changed files with 91 additions and 16 deletions
+10 -7
View File
@@ -27,6 +27,7 @@ import {queryClient} from 'lib/react-query'
import {TestCtrls} from 'view/com/testing/TestCtrls'
import {Provider as ShellStateProvider} from 'state/shell'
import {Provider as ModalStateProvider} from 'state/modals'
import {Provider as DialogStateProvider} from 'state/dialogs'
import {Provider as LightboxStateProvider} from 'state/lightbox'
import {Provider as MutedThreadsProvider} from 'state/muted-threads'
import {Provider as InvitesStateProvider} from 'state/invites'
@@ -115,13 +116,15 @@ function App() {
<MutedThreadsProvider>
<InvitesStateProvider>
<ModalStateProvider>
<LightboxStateProvider>
<I18nProvider>
<PortalProvider>
<InnerApp />
</PortalProvider>
</I18nProvider>
</LightboxStateProvider>
<DialogStateProvider>
<LightboxStateProvider>
<I18nProvider>
<PortalProvider>
<InnerApp />
</PortalProvider>
</I18nProvider>
</LightboxStateProvider>
</DialogStateProvider>
</ModalStateProvider>
</InvitesStateProvider>
</MutedThreadsProvider>
+10 -7
View File
@@ -17,6 +17,7 @@ import {ThemeProvider} from 'lib/ThemeContext'
import {queryClient} from 'lib/react-query'
import {Provider as ShellStateProvider} from 'state/shell'
import {Provider as ModalStateProvider} from 'state/modals'
import {Provider as DialogStateProvider} from 'state/dialogs'
import {Provider as LightboxStateProvider} from 'state/lightbox'
import {Provider as MutedThreadsProvider} from 'state/muted-threads'
import {Provider as InvitesStateProvider} from 'state/invites'
@@ -93,13 +94,15 @@ function App() {
<MutedThreadsProvider>
<InvitesStateProvider>
<ModalStateProvider>
<LightboxStateProvider>
<I18nProvider>
<PortalProvider>
<InnerApp />
</PortalProvider>
</I18nProvider>
</LightboxStateProvider>
<DialogStateProvider>
<LightboxStateProvider>
<I18nProvider>
<PortalProvider>
<InnerApp />
</PortalProvider>
</I18nProvider>
</LightboxStateProvider>
</DialogStateProvider>
</ModalStateProvider>
</InvitesStateProvider>
</MutedThreadsProvider>
+12
View File
@@ -1,4 +1,6 @@
import React from 'react'
import {useDialogStateContext} from '#/state/dialogs'
import {DialogContextProps, DialogControlProps} from '#/components/Dialog/types'
export const Context = React.createContext<DialogContextProps>({
@@ -10,10 +12,20 @@ export function useDialogContext() {
}
export function useDialogControl() {
const id = React.useId()
const control = React.useRef<DialogControlProps>({
open: () => {},
close: () => {},
})
const {activeDialogs} = useDialogStateContext()
React.useEffect(() => {
activeDialogs.current.set(id, control)
return () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
activeDialogs.current.delete(id)
}
}, [id, activeDialogs])
return {
ref: control,
+44
View File
@@ -0,0 +1,44 @@
import React from 'react'
import {DialogControlProps} from '#/components/Dialog'
const DialogContext = React.createContext<{
activeDialogs: React.MutableRefObject<
Map<string, React.MutableRefObject<DialogControlProps>>
>
}>({
activeDialogs: {
current: new Map(),
},
})
const DialogControlContext = React.createContext<{
closeAllDialogs(): void
}>({
closeAllDialogs: () => {},
})
export function useDialogStateContext() {
return React.useContext(DialogContext)
}
export function useDialogStateControlContext() {
return React.useContext(DialogControlContext)
}
export function Provider({children}: React.PropsWithChildren<{}>) {
const activeDialogs = React.useRef<
Map<string, React.MutableRefObject<DialogControlProps>>
>(new Map())
const closeAllDialogs = React.useCallback(() => {
activeDialogs.current.forEach(dialog => dialog.current.close())
}, [])
const context = React.useMemo(() => ({activeDialogs}), [])
const controls = React.useMemo(() => ({closeAllDialogs}), [closeAllDialogs])
return (
<DialogContext.Provider value={context}>
<DialogControlContext.Provider value={controls}>
{children}
</DialogControlContext.Provider>
</DialogContext.Provider>
)
}
+15 -1
View File
@@ -6,10 +6,12 @@ import {Button} from '#/components/Button'
import {H3, P} from '#/components/Typography'
import * as Dialog from '#/components/Dialog'
import * as Prompt from '#/components/Prompt'
import {useDialogStateControlContext} from '#/state/dialogs'
export function Dialogs() {
const control = Dialog.useDialogControl()
const prompt = Prompt.usePromptControl()
const {closeAllDialogs} = useDialogStateControlContext()
return (
<View style={[a.gap_md]}>
@@ -17,7 +19,10 @@ export function Dialogs() {
variant="outline"
color="secondary"
size="small"
onPress={() => control.open()}
onPress={() => {
control.open()
prompt.open()
}}
label="Open basic dialog">
Open basic dialog
</Button>
@@ -57,6 +62,15 @@ export function Dialogs() {
A scrollable dialog with an input within it.
</P>
<Dialog.Input value="" onChangeText={() => {}} label="Type here" />
<Button
variant="outline"
color="secondary"
size="small"
onPress={closeAllDialogs}
label="Close all dialogs">
Close all dialogs
</Button>
<View style={{height: 1000}} />
<View style={[a.flex_row, a.justify_end]}>
<Button
-1
View File
@@ -70,7 +70,6 @@ export function Forms() {
<View style={[a.w_full]}>
<Label>Date</Label>
<DateField
isInvalid
testID="date"
value={date}
onChangeDate={date => {