# Setup

Source: https://docs.interop.io/browser/capabilities/windows/modals/setup/index.html

## Overview

Available since io.Connect Browser 4.0

The [`@interopio/modals-api`](https://www.npmjs.com/package/@interopio/modals-api) and [`@interopio/modals-ui`](https://www.npmjs.com/package/@interopio/modals-libraries) libraries enable you to use modal windows (alerts and dialogs) in your **io.Connect Browser** projects.

The `@interopio/modals-api` library provides a convenient API for displaying and manipulating modal windows. You can use the Modals API with the default alert and dialog templates available via the `@interopio/modals-ui` library, as well as with your own [custom modal windows](#extending_the_modal_windows).

The `@interopio/modals-ui` library provides the UI for the modal windows - a set of predefined alerts and dialog templates which you can use in your apps by simply configuring their content.

**io.Connect Browser** allows you to replace the default alerts and dialogs with your own [custom modal windows](#extending_the_modal_windows) by decorating the `@interopio/modals-ui` library or by creating an entirely new library that implements the `@interopio/modals-ui` API.

## Enabling Modals

To be able to use the Modals API in your interop-enabled apps, install the [`@interopio/modals-api`](https://www.npmjs.com/package/@interopio/modals-api) library in your project and reference it in your app. Depending on whether you want to use the Modals API in your [Main app](https://docs.interop.io/browser/developers/browser-platform/overview/index.md), or in a [Browser Client](https://docs.interop.io/browser/developers/browser-client/overview/index.md) app, see the respective initialization examples in the following sections.

> ⚠️ *Note that enabling the Modals API and configuring the modal windows is required if you are using the [Home App](https://docs.interop.io/browser/capabilities/home-app/overview/index.md) to build your **io.Connect Browser** project. Modal windows are necessary for the Launchpad to function properly.*

## Main App

To use the default io.Connect modal windows in your **io.Connect Browser** project, you must:

-  Install the [`@interopio/modals-api`](https://www.npmjs.com/package/@interopio/modals-api) library in your [Main app](https://docs.interop.io/browser/developers/browser-platform/overview/index.md) and initialize it.

- Configure the io.Connect modal windows in the Main app - provide URLs pointing to the locations of the bundle, styles, and fonts for the modal windows, block any origins from using modal windows. You can use the default bundles, styles, and fonts provided by the [`@interopio/modals-ui`](https://www.npmjs.com/package/@interopio/modals-libraries) library.

- Explicitly enable or disable using alerts and dialogs in the configuration object for the internal initialization of the [`@interopio/browser`](https://www.npmjs.com/package/@interopio/browser) library in the Main app.

Install the necessary packages:

```cmd
npm install @interopio/browser-platform @interopio/modals-api
```

Use the `modals` property of the configuration object for initializing the [`@interopio/browser-platform`](https://www.npmjs.com/package/@interopio/browser-platform) library to define the sources of the modal windows to be used by the platform. Enable the Modals API by passing the `IOModals()` factory function to the `libraries` array of the `browser` object used for the internal initialization of the [`@interopio/browser`](https://www.npmjs.com/package/@interopio/browser) library:

```javascript
import IOBrowserPlatform from "@interopio/browser-platform";
import IOModals from "@interopio/modals-api";

const config = {
    licenseKey: "my-license-key",
    // Settings for the modal windows to be used in the platform.
    modals: {
        sources: {
            // It's required to specify the locations of the bundle and styles for the modal windows.
            // You can use the resources provided by the `@interopio/modals-ui` library
            // or provide your own custom library that implements the `@interopio/modals-ui` API.
            bundle: "https://my-modals/modals-bundle.js",
            styles: ["https://my-modals/styles.css", "https://example.com/custom-styles.css"],
            // It's required to specify the fonts when using the default modal windows
            // provided by the `@interopio/modals-ui` library.
            fonts: ["https://my-modals/fonts.css"]
        }
    },
    browser: {
        // Enabling the Modals API.
        libraries: [IOModals],
        // Enabling the Main app to use modal windows.
        modals: {
            alerts: {
                enabled: true
            },
            dialogs: {
                enabled: true
            }
        }
    }
};

const { io } = await IOBrowserPlatform(config);

// Now you can access the Modals API via `io.modals`.
```

The `modals` object has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `blockList` | `string[]` | List of origins to block from using modal windows (e.g., `["https://example.com/*"]`). |
| `sources` | `object` | **Required.** Use to specify the locations of the bundle, styles, and fonts for the modal windows. |

The `sources` object has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `bundle` | `string` | **Required.** URL pointing to the location of the modal windows bundle. The bundle must be hosted in order for Browser Client apps to be able to use it. If you provide it as a static resource, only the Main app will be able to use it. |
| `fonts` | `string[]` | List of URLs pointing to the locations of the fonts for the modal windows. |
| `styles` | `string[]` | **Required.** List of URLs pointing to the locations of the styles for the modal windows. |

## Browser Clients

To enable the Modals API in your [Browser Client](https://docs.interop.io/browser/developers/browser-client/overview/index.md) apps, install the [`@interopio/browser`](https://www.npmjs.com/package/@interopio/browser) and [`@interopio/modals-api`](https://www.npmjs.com/package/@interopio/modals-api) libraries and initialize the [`@interopio/browser`](https://www.npmjs.com/package/@interopio/browser) library by passing the `IOModals()` factory function in the configuration object. You must also explicitly enable or disable using alerts and dialogs in the Browser Client. When `IOBrowser()` resolves, the Modals API will be accessible via the `modals` property of the returned object - e.g., `io.modals`. The following examples demonstrate how to enable the Modals API in JavaScript, React, and Angular apps.

### JavaScript

Install the necessary packages:

```cmd
npm install @interopio/browser @interopio/modals-api
```

Initialize the [`@interopio/browser`](https://www.npmjs.com/package/@interopio/browser) library, pass the `IOModals()` factory function to the `libraries` array of the configuration object for initializing the library, and enable the Browser Client to use alerts and dialogs:

```javascript
import IOBrowser from "@interopio/desktop";
import IOModals from "@interopio/modals-api";

// Initializing the Modals API.
const config = {
    libraries: [IOModals],
    // Enabling the Browser Client to use modal windows.
    modals: {
        alerts: {
            enabled: true
        },
        dialogs: {
            enabled: true
        }
    }
};

const io = await IOBrowser(config);

// Now you can access the Modals API via `io.modals`.
```

By default, the `IOBrowser()` and `IOModals()` factory functions are injected in the global `window` object.

### React

Install the necessary packages:

```cmd
npm install @interopio/react-hooks @interopio/modals-api
```

Initialize the [`@interopio/react-hooks`](https://www.npmjs.com/package/@interopio/react-hooks) library in one of the following ways, pass the `IOModals()` factory function to the `libraries` array of the configuration object for initializing the library, and enable the Browser Client to use alerts and dialogs.

- using the `<IOConnectProvider />` component:

```javascript
import { createRoot } from "react-dom/client";
import { IOConnectProvider } from "@interopio/react-hooks";
import IOBrowser from "@interopio/browser";
import IOModals from "@interopio/modals-api";

const settings = {
    browser: {
        factory: IOBrowser,
        config: {
            libraries: [IOModals],
            // Enabling the Browser Client to use modal windows.
            modals: {
                alerts: {
                    enabled: true
                },
                dialogs: {
                    enabled: true
                }
            }
        }
    }
};

const domElement = document.getElementById("root");
const root = createRoot(domElement);

root.render(
    <IOConnectProvider fallback={<h2>Loading...</h2>} settings={settings}>
        <App />
    </IOConnectProvider>
);
```

-  using the `useIOConnectInit()` hook:

```javascript
import { useIOConnectInit } from "@interopio/react-hooks";
import IOBrowser from "@interopio/browser";
import IOModals from "@interopio/modals-api";

const App = () => {
    const settings = {
        browser: {
            factory: IOBrowser,
            config: {
                libraries: [IOModals],
                // Enabling the Browser Client to use modal windows.
                modals: {
                    alerts: {
                        enabled: true
                    },
                    dialogs: {
                        enabled: true
                    }
                }
            }
        }
    };

    const io = useIOConnectInit(settings);

    return io ? <Main io={io} /> : <Loader />;
};

export default App;
```

### Angular

Install the necessary packages:

```cmd
npm install @interopio/ng @interopio/modals-api
```

Initialize the [`@interopio/ng`](https://www.npmjs.com/package/@interopio/ng) library, pass the `IOModals()` factory function to the `libraries` array of the configuration object for initializing the library, and enable the Browser Client to use alerts and dialogs.

In `app.config.ts` of the Browser Client app:

```typescript
import { ApplicationConfig } from "@angular/core";
import { provideIoConnect } from "@interopio/ng";
import IOBrowser, { IOConnectBrowser } from "@interopio/browser";
import IOModals from "@interopio/modals-api";

const config: IOConnectBrowser.Config = {
    libraries: [IOModals],
    // Enabling the Browser Client to use modal windows.
    modals: {
        alerts: {
            enabled: true
        },
        dialogs: {
            enabled: true
        }
    }
};

export const appConfig: ApplicationConfig = {
    providers: [
        provideIoConnect({
            browser: {
                factory: IOBrowser,
                config
            }
        })
    ]
};
```

> ℹ️ *For more details on initializing and configuring the `@interopio/ng` library depending on whether you are using Angular standalone components or modules, see the [Developers > Browser Client > Angular](https://docs.interop.io/browser/developers/browser-client/angular/index.md) section.*

## Extending the Modal Windows

To use your own custom alerts and dialogs, you can either decorate the [`@interopio/modals-ui`](https://www.npmjs.com/package/@interopio/modals-libraries) library or create your own modal windows library that implements the `@interopio/modals-ui` API.

> ⚠️ *Note that in order for the io.Connect platform to be able to use a custom library for displaying modal windows, it's required for this custom library to implement the `@interopio/modals-ui` API. The structure of the `@interopio/modals-ui` API is described in the `modals.ui.d.ts` file distributed with the library.*

After decorating the `@interopio/modals-ui` library or implementing your custom modal windows, you must create and export a custom factory function and attach it to the global `window` object as `IOBrowserModalsUI()`. The factory function accepts as a first required argument the io.Connect API object returned from initializing the [`@interopio/browser`](https://www.npmjs.com/package/@interopio/browser) library. As a second required argument, it accepts a configuration object for the `@interopio/modals-ui` library.

The following example demonstrates how to create your custom factory function and attach it to the global `window` object:

```javascript
import IOBrowserModalsUI from "@interopio/modals-ui";

// Define your custom factory function that accepts the initialized io.Connect API object
// and a configuration object for the `@interopio/modals-ui` library.
const MyCustomIOBrowserModalsUI = async (io, config) => {

    // Decorate the `@interopio/modals-ui` library or create your own custom modal windows
    // library that implements the `@interopio/modals-ui` API.

    // Return the invocation of the default factory function if you want to decorate the library.
    return IOBrowserModalsUI(io, config);
};

if (typeof window !== "undefined") {
    // Inject your custom factory function in the global `window` object as `IOBrowserModalsUI`.
    window.IOBrowserModalsUI = MyCustomIOBrowserModalsUI;
};

export default MyCustomIOBrowserModalsUI;
```

To instruct the io.Connect platform to use your custom modal windows library, use the `sources` property of the `modals` top-level key in the configuration object for initializing the [`@interopio/browser-platform`](https://www.npmjs.com/package/@interopio/browser-platform) library to provide URLs pointing to the locations of your custom library bundle and styles:

```javascript
import IOBrowserPlatform from "@interopio/browser-platform";
import IOModals from "@interopio/modals-api";

const config = {
    licenseKey: "my-license-key",
    modals: {
        sources: {
            // Provide the locations of your custom library bundle and styles.
            bundle: "https://my-modals/my-custom-bundle.js",
            styles: ["https://my-modals/my-custom-styles.css"]
        }
    },
    browser: {
        // Enabling the Modals API.
        libraries: [IOModals],
        // Enabling the Main app to use modal windows.
        modals: {
            alerts: {
                enabled: true
            },
            dialogs: {
                enabled: true
            }
        }
    }
};

const { io } = await IOBrowserPlatform(config);
```

## Styles

To customize the styles of the io.Connect modal windows, use the [CSS variables](https://docs.interop.io/browser/developers/platform-styles/index.md#modals) provided by the io.Connect themes.
