You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
2.0 KiB
90 lines
2.0 KiB
import { Dialog as MuiDialog, SxProps, Theme } from '@mui/material'; |
|
import { |
|
ForwardRefExoticComponent, |
|
PropsWithChildren, |
|
ReactNode, |
|
RefAttributes, |
|
createContext, |
|
forwardRef, |
|
useImperativeHandle, |
|
useMemo, |
|
useState, |
|
} from 'react'; |
|
|
|
import { Panel } from '../Panels'; |
|
import Spinner from '../Spinner'; |
|
|
|
const DialogContext = createContext<DialogContextContent | undefined>( |
|
undefined, |
|
); |
|
|
|
const Dialog: ForwardRefExoticComponent< |
|
PropsWithChildren<DialogProps> & RefAttributes<DialogForwardedRefContent> |
|
> = forwardRef<DialogForwardedRefContent, DialogProps>((props, ref) => { |
|
const { |
|
children: externalChildren, |
|
dialogProps = {}, |
|
loading, |
|
openInitially = false, |
|
wide, |
|
} = props; |
|
|
|
const { |
|
// Do not initialize the external open state because we need it to |
|
// determine whether the dialog is controlled or uncontrolled. |
|
open: externalOpen, |
|
PaperProps: paperProps = {}, |
|
...restDialogProps |
|
} = dialogProps; |
|
|
|
const { sx: externalPaperSx, ...restPaperProps } = paperProps; |
|
|
|
const [controlOpen, setControlOpen] = useState<boolean>(openInitially); |
|
|
|
const open = useMemo<boolean>( |
|
() => externalOpen ?? controlOpen, |
|
[controlOpen, externalOpen], |
|
); |
|
|
|
const children = useMemo<ReactNode>( |
|
() => (loading ? <Spinner mt={0} /> : externalChildren), |
|
[externalChildren, loading], |
|
); |
|
|
|
const paperSx = useMemo<SxProps<Theme>>( |
|
() => ({ |
|
minWidth: wide ? { xs: 'calc(100%)', md: '50em' } : null, |
|
overflow: 'visible', |
|
...externalPaperSx, |
|
}), |
|
[externalPaperSx, wide], |
|
); |
|
|
|
useImperativeHandle( |
|
ref, |
|
() => ({ |
|
open, |
|
setOpen: setControlOpen, |
|
}), |
|
[open], |
|
); |
|
|
|
return ( |
|
<MuiDialog |
|
open={open} |
|
PaperComponent={Panel} |
|
PaperProps={{ ...restPaperProps, sx: paperSx }} |
|
{...restDialogProps} |
|
> |
|
<DialogContext.Provider value={{ open, setOpen: setControlOpen }}> |
|
{children} |
|
</DialogContext.Provider> |
|
</MuiDialog> |
|
); |
|
}); |
|
|
|
Dialog.displayName = 'Dialog'; |
|
|
|
export { DialogContext }; |
|
|
|
export default Dialog;
|
|
|