JumboDialog

JumboDialog is a centralized dialog system in the @jumbo framework. It renders a single <JumboDialog /> at the app level, controlled by JumboDialogProvider. Any component anywhere in the tree can open, update, or close the dialog using the useJumboDialog hook — no local state or prop drilling required.

Provider setup

JumboDialogProvider and <JumboDialog /> are mounted once in the root layout:

tsx
// src/app/[lang]/layout.tsx (excerpt)
import { JumboDialogProvider } from '@jumbo/components/JumboDialog';
import { JumboDialog } from '@jumbo/components/JumboDialog';
 
export default function RootLayout({ children }) {
  return (
    <JumboDialogProvider>
      <JumboDialog />
      {children}
    </JumboDialogProvider>
  );
}

useJumboDialog hook

useJumboDialog returns methods for controlling the shared dialog:

typescript
import { useJumboDialog } from '@jumbo/components/JumboDialog';
 
const { showDialog, hideDialog, updateDialog } = useJumboDialog();
MethodSignatureDescription
showDialog(options: DialogOptions) => voidOpens the dialog with the given options
hideDialog() => voidCloses and resets the dialog
updateDialog(options: Partial<DialogOptions>) => voidUpdates options while dialog is open

DialogOptions

typescript
interface DialogOptions {
  title?:          string;
  content?:        ReactNode;   // Any JSX to render as the dialog body
  actions?:        ReactNode;   // Footer actions (e.g. Confirm/Cancel buttons)
  maxWidth?:       DialogProps['maxWidth'];  // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
  fullWidth?:      boolean;
  onClose?:        () => void;  // Called when dialog is closed
}

Opening a basic dialog

tsx
'use client';
 
import { useJumboDialog } from '@jumbo/components/JumboDialog';
import { Button } from '@mui/material';
 
export function DeleteButton({ itemName }: { itemName: string }) {
  const { showDialog, hideDialog } = useJumboDialog();
 
  const handleDelete = () => {
    showDialog({
      title: 'Confirm Deletion',
      content: <p>Are you sure you want to delete <strong>{itemName}</strong>?</p>,
      actions: (
        <>
          <Button onClick={hideDialog}>Cancel</Button>
          <Button color="error" onClick={() => { performDelete(); hideDialog(); }}>
            Delete
          </Button>
        </>
      ),
    });
  };
 
  return <Button color="error" onClick={handleDelete}>Delete</Button>;
}

Confirm dialog pattern

For simple yes/no confirmations, pass a concise content and two action buttons:

tsx
'use client';
 
import { useJumboDialog } from '@jumbo/components/JumboDialog';
import { Button, Typography } from '@mui/material';
 
export function useConfirmDialog() {
  const { showDialog, hideDialog } = useJumboDialog();
 
  const confirm = (message: string, onConfirm: () => void) => {
    showDialog({
      title: 'Are you sure?',
      content: <Typography>{message}</Typography>,
      maxWidth: 'xs',
      fullWidth: true,
      actions: (
        <>
          <Button onClick={hideDialog}>Cancel</Button>
          <Button
            variant="contained"
            onClick={() => { onConfirm(); hideDialog(); }}
          >
            Confirm
          </Button>
        </>
      ),
    });
  };
 
  return { confirm };
}

Rendering custom content

The content prop accepts any ReactNode, including full forms:

tsx
showDialog({
  title: 'Edit Profile',
  content: <EditProfileForm onSuccess={hideDialog} />,
  maxWidth: 'sm',
  fullWidth: true,
});