Add closeAllDialogs control
This commit is contained in:
+10
-7
@@ -27,6 +27,7 @@ import {queryClient} from 'lib/react-query'
|
|||||||
import {TestCtrls} from 'view/com/testing/TestCtrls'
|
import {TestCtrls} from 'view/com/testing/TestCtrls'
|
||||||
import {Provider as ShellStateProvider} from 'state/shell'
|
import {Provider as ShellStateProvider} from 'state/shell'
|
||||||
import {Provider as ModalStateProvider} from 'state/modals'
|
import {Provider as ModalStateProvider} from 'state/modals'
|
||||||
|
import {Provider as DialogStateProvider} from 'state/dialogs'
|
||||||
import {Provider as LightboxStateProvider} from 'state/lightbox'
|
import {Provider as LightboxStateProvider} from 'state/lightbox'
|
||||||
import {Provider as MutedThreadsProvider} from 'state/muted-threads'
|
import {Provider as MutedThreadsProvider} from 'state/muted-threads'
|
||||||
import {Provider as InvitesStateProvider} from 'state/invites'
|
import {Provider as InvitesStateProvider} from 'state/invites'
|
||||||
@@ -115,13 +116,15 @@ function App() {
|
|||||||
<MutedThreadsProvider>
|
<MutedThreadsProvider>
|
||||||
<InvitesStateProvider>
|
<InvitesStateProvider>
|
||||||
<ModalStateProvider>
|
<ModalStateProvider>
|
||||||
<LightboxStateProvider>
|
<DialogStateProvider>
|
||||||
<I18nProvider>
|
<LightboxStateProvider>
|
||||||
<PortalProvider>
|
<I18nProvider>
|
||||||
<InnerApp />
|
<PortalProvider>
|
||||||
</PortalProvider>
|
<InnerApp />
|
||||||
</I18nProvider>
|
</PortalProvider>
|
||||||
</LightboxStateProvider>
|
</I18nProvider>
|
||||||
|
</LightboxStateProvider>
|
||||||
|
</DialogStateProvider>
|
||||||
</ModalStateProvider>
|
</ModalStateProvider>
|
||||||
</InvitesStateProvider>
|
</InvitesStateProvider>
|
||||||
</MutedThreadsProvider>
|
</MutedThreadsProvider>
|
||||||
|
|||||||
+10
-7
@@ -17,6 +17,7 @@ import {ThemeProvider} from 'lib/ThemeContext'
|
|||||||
import {queryClient} from 'lib/react-query'
|
import {queryClient} from 'lib/react-query'
|
||||||
import {Provider as ShellStateProvider} from 'state/shell'
|
import {Provider as ShellStateProvider} from 'state/shell'
|
||||||
import {Provider as ModalStateProvider} from 'state/modals'
|
import {Provider as ModalStateProvider} from 'state/modals'
|
||||||
|
import {Provider as DialogStateProvider} from 'state/dialogs'
|
||||||
import {Provider as LightboxStateProvider} from 'state/lightbox'
|
import {Provider as LightboxStateProvider} from 'state/lightbox'
|
||||||
import {Provider as MutedThreadsProvider} from 'state/muted-threads'
|
import {Provider as MutedThreadsProvider} from 'state/muted-threads'
|
||||||
import {Provider as InvitesStateProvider} from 'state/invites'
|
import {Provider as InvitesStateProvider} from 'state/invites'
|
||||||
@@ -93,13 +94,15 @@ function App() {
|
|||||||
<MutedThreadsProvider>
|
<MutedThreadsProvider>
|
||||||
<InvitesStateProvider>
|
<InvitesStateProvider>
|
||||||
<ModalStateProvider>
|
<ModalStateProvider>
|
||||||
<LightboxStateProvider>
|
<DialogStateProvider>
|
||||||
<I18nProvider>
|
<LightboxStateProvider>
|
||||||
<PortalProvider>
|
<I18nProvider>
|
||||||
<InnerApp />
|
<PortalProvider>
|
||||||
</PortalProvider>
|
<InnerApp />
|
||||||
</I18nProvider>
|
</PortalProvider>
|
||||||
</LightboxStateProvider>
|
</I18nProvider>
|
||||||
|
</LightboxStateProvider>
|
||||||
|
</DialogStateProvider>
|
||||||
</ModalStateProvider>
|
</ModalStateProvider>
|
||||||
</InvitesStateProvider>
|
</InvitesStateProvider>
|
||||||
</MutedThreadsProvider>
|
</MutedThreadsProvider>
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
|
import {useDialogStateContext} from '#/state/dialogs'
|
||||||
import {DialogContextProps, DialogControlProps} from '#/components/Dialog/types'
|
import {DialogContextProps, DialogControlProps} from '#/components/Dialog/types'
|
||||||
|
|
||||||
export const Context = React.createContext<DialogContextProps>({
|
export const Context = React.createContext<DialogContextProps>({
|
||||||
@@ -10,10 +12,20 @@ export function useDialogContext() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function useDialogControl() {
|
export function useDialogControl() {
|
||||||
|
const id = React.useId()
|
||||||
const control = React.useRef<DialogControlProps>({
|
const control = React.useRef<DialogControlProps>({
|
||||||
open: () => {},
|
open: () => {},
|
||||||
close: () => {},
|
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 {
|
return {
|
||||||
ref: control,
|
ref: control,
|
||||||
|
|||||||
@@ -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>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -6,10 +6,12 @@ import {Button} from '#/components/Button'
|
|||||||
import {H3, P} from '#/components/Typography'
|
import {H3, P} from '#/components/Typography'
|
||||||
import * as Dialog from '#/components/Dialog'
|
import * as Dialog from '#/components/Dialog'
|
||||||
import * as Prompt from '#/components/Prompt'
|
import * as Prompt from '#/components/Prompt'
|
||||||
|
import {useDialogStateControlContext} from '#/state/dialogs'
|
||||||
|
|
||||||
export function Dialogs() {
|
export function Dialogs() {
|
||||||
const control = Dialog.useDialogControl()
|
const control = Dialog.useDialogControl()
|
||||||
const prompt = Prompt.usePromptControl()
|
const prompt = Prompt.usePromptControl()
|
||||||
|
const {closeAllDialogs} = useDialogStateControlContext()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={[a.gap_md]}>
|
<View style={[a.gap_md]}>
|
||||||
@@ -17,7 +19,10 @@ export function Dialogs() {
|
|||||||
variant="outline"
|
variant="outline"
|
||||||
color="secondary"
|
color="secondary"
|
||||||
size="small"
|
size="small"
|
||||||
onPress={() => control.open()}
|
onPress={() => {
|
||||||
|
control.open()
|
||||||
|
prompt.open()
|
||||||
|
}}
|
||||||
label="Open basic dialog">
|
label="Open basic dialog">
|
||||||
Open basic dialog
|
Open basic dialog
|
||||||
</Button>
|
</Button>
|
||||||
@@ -57,6 +62,15 @@ export function Dialogs() {
|
|||||||
A scrollable dialog with an input within it.
|
A scrollable dialog with an input within it.
|
||||||
</P>
|
</P>
|
||||||
<Dialog.Input value="" onChangeText={() => {}} label="Type here" />
|
<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={{height: 1000}} />
|
||||||
<View style={[a.flex_row, a.justify_end]}>
|
<View style={[a.flex_row, a.justify_end]}>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -70,7 +70,6 @@ export function Forms() {
|
|||||||
<View style={[a.w_full]}>
|
<View style={[a.w_full]}>
|
||||||
<Label>Date</Label>
|
<Label>Date</Label>
|
||||||
<DateField
|
<DateField
|
||||||
isInvalid
|
|
||||||
testID="date"
|
testID="date"
|
||||||
value={date}
|
value={date}
|
||||||
onChangeDate={date => {
|
onChangeDate={date => {
|
||||||
|
|||||||
Reference in New Issue
Block a user