Modals manager

Centralized modals manager with option to handle state of multi-step modals
Import
License

Installation

Package depends on @mantine/core and @mantine/hooks.

Install with yarn:

yarn add @mantine/modals

Install with npm:

npm install @mantine/modals

Setup ModalsProvider

Wrap your app with ModalsProvider component:

import { MantineProvider } from '@mantine/core';
import { ModalsProvider } from '@mantine/modals';
function Demo() {
return (
<MantineProvider>
<ModalsProvider>
<App />
</ModalsProvider>
</MantineProvider>
);
}

Confirm modal

@mantine/modals package includes special modal that can be used for confirmations. Component includes confirm and cancel buttons and supports children to display additional information about action. Use openConfirmModal function to open a confirm modal:

import { Button, Text } from '@mantine/core';
import { openConfirmModal } from '@mantine/modals';
function Demo() {
const openModal = () => openConfirmModal({
title: 'Please confirm your action',
children: (
<Text size="sm">
This action is so important that you are required to confirm it with a modal. Please click
one of these buttons to proceed.
</Text>
),
labels: { confirm: 'Confirm', cancel: 'Cancel' },
onCancel: () => console.log('Cancel'),
onConfirm: () => console.log('Confirmed'),
});
return <Button onClick={openModal}>Open confirm modal</Button>;
}

openConfirmModal function accepts one argument with following properties:

  • modalId – modal id, defaults to random id, can be used to close modal programmatically
  • children – additional modal content displayed before actions
  • onCancel – called when cancel button is clicked
  • onConfirm – called when confirm button is clicked
  • closeOnConfirm – should modal be closed when confirm button is clicked, defaults to true
  • closeOnCancel – should modal be closed when cancel button is clicked, defaults to true
  • cancelProps – cancel button props
  • confirmProps – confirm button props
  • groupProps – buttons Group props
  • labels – cancel and confirm buttons labels, can be defined on ModalsProvider

Using this properties you can customize confirm modal to match current context requirements:

import { Button, Text } from '@mantine/core';
import { openConfirmModal } from '@mantine/modals';
function Demo() {
const openDeleteModal = () =>
openConfirmModal({
title: 'Delete your profile',
centered: true,
children: (
<Text size="sm">
Are you sure you want to delete your profile? This action is destructive and you will have
to contact support to restore your data.
</Text>
),
labels: { confirm: 'Delete account', cancel: "No don't delete it" },
confirmProps: { color: 'red' },
onCancel: () => console.log('Cancel'),
onConfirm: () => console.log('Confirmed'),
});
return <Button onClick={openDeleteModal} color="red">Delete account</Button>;
}

To setup shared labels for confirm modals set labels on ModalsProvider:

import { ModalsProvider } from '@mantine/modals';
function Demo() {
return (
<ModalsProvider labels={{ confirm: 'Submit', cancel: 'Cancel' }}>
<App />
</ModalsProvider>
);
}

Context modals

You can define any amount of modals in ModalsProvider context:

import { ContextModalProps, ModalsProvider } from '@mantine/modals';
import { Text, Button } from '@mantine/core';
const TestModal = ({ context, id, innerProps }: ContextModalProps<{ modalBody: string }>) => (
<>
<Text size="sm">{innerProps.modalBody}</Text>
<Button fullWidth mt="md" onClick={() => context.closeModal(id)}>
Close modal
</Button>
</>
);
function Demo() {
return (
<ModalsProvider modals={{ demonstration: TestModal /* ...other modals */ }}>
<App />
</ModalsProvider>
);
}

And then open one of these modals with openContextModal function. openContextModal function accepts 2 arguments: modal key (should match one defined on ModalsProvider) and modal props:

import { Button, Group } from '@mantine/core';
import { openContextModal } from '@mantine/modals';
function Demo() {
return (
<Group position="center">
<Button
onClick={() =>
openContextModal({
modal: 'demonstration',
title: 'Test modal from context',
innerProps: {
modalBody:
'This modal was defined in ModalsProvider, you can open it anywhere in you app with useModals hook',
},
})
}
>
Open demonstration context modal
</Button>
</Group>
);
}

Content modals

With openModal function you can open a modal with any content:

import { TextInput, Button, Group } from '@mantine/core';
import { openModal, closeAllModals } from '@mantine/modals';
function Demo() {
return (
<Group position="center">
<Button
onClick={() => {
openModal({
title: 'Subscribe to newsletter',
children: (
<>
<TextInput label="Your email" placeholder="Your email" data-autofocus />
<Button fullWidth onClick={closeAllModals} mt="md">
Submit
</Button>
</>
),
});
}}
>
Open content modal
</Button>
</Group>
);
}

Multiple opened modals

You can open multiple layers of modals. Every opened modal is added as first element in modals queue. To close all opened modals call modals.closeAll() function:

import { Group, Button, Text } from '@mantine/core';
import { openConfirmModal, closeAllModals } from '@mantine/modals';
function Demo() {
return (
<Group position="center">
<Button
onClick={() =>
openConfirmModal({
title: 'Please confirm your action',
closeOnConfirm: false,
labels: { confirm: 'Next modal', cancel: 'Close modal' },
children: (
<Text size="sm">
This action is so important that you are required to confirm it with a modal. Please
click one of these buttons to proceed.
</Text>
),
onConfirm: () =>
openConfirmModal({
title: 'This is modal at second layer',
labels: { confirm: 'Close modal', cancel: 'Back' },
closeOnConfirm: false,
children: (
<Text size="sm">
When this modal is closed modals state will revert to first modal
</Text>
),
onConfirm: closeAllModals,
}),
})
}
>
Open multiple steps modal
</Button>
</Group>
);
}

ModalsProvider component props

NameTypeDescription
children *
ReactNode
Your app
labels
ConfirmLabels
Confirm modal labels
modalProps
ModalSettings
Shared Modal component props, applied for every modal
modals
Record<string, FC<ContextModalProps<any>>>
Predefined modals