21
common/resources/client/ui/overlays/store/dialog-store-outlet.tsx
Executable file
21
common/resources/client/ui/overlays/store/dialog-store-outlet.tsx
Executable file
@@ -0,0 +1,21 @@
|
||||
import {
|
||||
closeDialog,
|
||||
useDialogStore,
|
||||
} from '@common/ui/overlays/store/dialog-store';
|
||||
import {DialogTrigger} from '@common/ui/overlays/dialog/dialog-trigger';
|
||||
import React from 'react';
|
||||
|
||||
export function DialogStoreOutlet() {
|
||||
const {dialog: DialogElement, data} = useDialogStore();
|
||||
return (
|
||||
<DialogTrigger
|
||||
type="modal"
|
||||
isOpen={DialogElement != null}
|
||||
onClose={value => {
|
||||
closeDialog(value);
|
||||
}}
|
||||
>
|
||||
{DialogElement ? <DialogElement {...data} /> : null}
|
||||
</DialogTrigger>
|
||||
);
|
||||
}
|
||||
44
common/resources/client/ui/overlays/store/dialog-store.ts
Executable file
44
common/resources/client/ui/overlays/store/dialog-store.ts
Executable file
@@ -0,0 +1,44 @@
|
||||
import {create} from 'zustand';
|
||||
import {immer} from 'zustand/middleware/immer';
|
||||
import React, {JSXElementConstructor} from 'react';
|
||||
|
||||
interface DialogStore<
|
||||
C extends JSXElementConstructor<unknown> = JSXElementConstructor<any>,
|
||||
D = React.ComponentProps<C>
|
||||
> {
|
||||
dialog: C | null;
|
||||
data: D;
|
||||
openDialog: (dialog: C, data?: D) => Promise<any>;
|
||||
closeActiveDialog: (value: any) => void;
|
||||
resolveClosePromise: null | ((value: any) => void);
|
||||
}
|
||||
|
||||
export const useDialogStore = create<DialogStore>()(
|
||||
immer((set, get) => ({
|
||||
dialog: null,
|
||||
data: undefined,
|
||||
resolveClosePromise: null,
|
||||
openDialog: (dialog, data) => {
|
||||
return new Promise(resolve => {
|
||||
set(state => {
|
||||
state.dialog = dialog;
|
||||
state.data = data;
|
||||
state.resolveClosePromise = resolve;
|
||||
});
|
||||
});
|
||||
},
|
||||
closeActiveDialog: value => {
|
||||
get().resolveClosePromise?.(value);
|
||||
set(state => {
|
||||
state.dialog = null;
|
||||
state.data = undefined;
|
||||
state.resolveClosePromise = null;
|
||||
});
|
||||
},
|
||||
}))
|
||||
);
|
||||
|
||||
export const openDialog = useDialogStore.getState().openDialog;
|
||||
export const closeDialog = (value?: any) => {
|
||||
useDialogStore.getState().closeActiveDialog(value);
|
||||
};
|
||||
Reference in New Issue
Block a user