> ## Documentation Index
> Fetch the complete documentation index at: https://docs.activeviam.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a popup

> How to add popups and modals to Atoti UI using the Ant Design Modal component or the useModal hook, including making a modal compatible with useModal, registering it in Configuration.modals, and opening it programmatically with openModal.

The recommended way to add a popup or modal to your application is to use [the Ant Design Modal component](https://ant.design/components/modal).

<Warning>
  In some situations, using this component will not work. This happens in particular when the modal is opened from a submenu item. You can fix this issue by using the [`useModal`](../../reference/hooks#usemodal) hook.
</Warning>

## The [`useModal`](../../reference/hooks#usemodal) hook

To use this hook, you must:

* [Make your modal compatible with it](#make-a-modal-compatible-with-usemodal).
* [Register your modal](#register-a-modal).
* [Open the modal using the hook](#open-a-modal).

### Making a modal compatible with [`useModal`](../../reference/hooks#usemodal)

Assuming you have a component named `MyModal`, that renders your modal:

```typescript theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
import { Modal } from "antd";
import { FC, useState } from "react";

const MyModal: FC<MyModalProps> = (props) => {
  const [open, setOpen] = useState(true);

  return (
    <Modal
      open={open}
      onOk={() => setOpen(false)}
      onCancel={() => setOpen(false)}
    >
      ...
    </Modal>
  );
};
```

To make it compatible with [`useModal`](../../reference/hooks#usemodal), apply these changes:

```typescript {4-4,8-9,16-21} theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
import { Modal } from "antd";
import { FC, useState } from "react";

import { useModal } from "@activeviam/atoti-ui-sdk";

const MyModal: FC<MyModalProps> = (props) => {
  const [open, setOpen] = useState(true);
  // The `closeModal` function unmounts the modal.
  const { closeModal } = useModal();

  return (
    <Modal
      open={open}
      onOk={() => setOpen(false)}
      onCancel={() => setOpen(false)}
      // Unmount the modal after the closing animation.
      afterOpenChange={(isOpen) => {
        if (!isOpen) {
          closeModal();
        }
      }}
    >
      ...
    </Modal>
  );
};
```

### Register a modal

After you've made your modal compatible with [`useModal`](../../reference/hooks#usemodal), register it in the extension's [Configuration](../../reference/types#configuration) in your `index.ts`:

```typescript {3-6} theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
const extension: ExtensionModule = {
  activate: async (configuration) => {
    configuration.modals = {
      ...configuration.modals,
      "my-modal": MyModal,
    };
  },
};
```

### Open a modal

Once your modal is compatible with [`useModal`](../../reference/hooks#usemodal) and it is registered, you can open it as follows:

```typescript {1-1,4-4,7-7} theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
import { useModal } from "@activeviam/atoti-ui-sdk";

const Component = () => {
  const { openModal } = useModal();

  const handleOnClick = () => {
    openModal<MyModalProps>("my-modal", props);
  };

  return <button onClick={handleOnClick}>Click me to open a modal</button>;
};
```

<Note>
  Notice how you can pass initial props to your modal component and define its
  props interface using TypeScript.
</Note>
