The Modal class enables your Custom UI app to open a modal dialog with a specified resource.
The Modal bridge API is exclusive to Custom UI; If you are using UI Kit, you can use the UI Kit Modal component instead.
1 2interface ModalOptions { resource?: string | null; onClose?: (payload?: any) => any; size?: 'small' | 'medium' | 'large' | 'xlarge' | 'max' | 'fullscreen' | 'resizable' | { width: string; height: string }; context?: any; closeOnEscape?: boolean; closeOnOverlayClick?: boolean; title?: string; icon?: string; } class Modal { constructor(opts?: ModalOptions); open(): Promise<void>; }
resource: The key of the static resource to open in the modal dialog. If not provided, the resource
defaults to the current resource. If your resource defines multiple entry points, you can target a specific
entry using the <resource-key>/<entry-key> syntax. Only Custom UI entries are supported, and the
entry's HTML file must be named <entry-key>.html (for example, an entry key of settings resolves
to settings.html). See Resources — Multiple entry points.
onClose: A callback function to run when the modal dialog is closed. The function accepts an
optional payload that is passed when calling view.close(payload) from inside the modal resource.
size: The size of the modal dialog.
400px h: 20vh minHeight: 320px600px h: 40vh minHeight: 520px800px h: 70vh minHeight: 720px968px h: 90vh100% h: 100%100vw h: 100vh (fills entire viewport, and title and icon will be displayed in the header)auto h: auto. The constraints for resizable are: minHeight: 320px, minWidth: 400px, maxHeight: 100% and maxWidth: calc(100vw - 120px)string h: string. Accepts any common CSS size string for width and height, e.g. '500px', '60vh'.context: Custom context that can be added to the context in the modal resource. It will appear
under the extension.modal key in the context object returned from view.getContext().
closeOnEscape: If set to false, the modal will not close when pressing escape.
closeOnOverlayClick: If set to false, the modal will not close when clicking the overlay.
title: If provided, the modal will render a header with the title and a close button.
icon: If provided, the modal will render a header with an icon next to the title, and a close button.
The resizable size behaviour has been provided to accommodate apps with content-driven sizing — for example, rendering a list with an unknown number of items. We recommend using this as a last resort over fixed modal dimensions, to avoid unexpected layout shifts and a jarring user experience.
To ensure the iframe resizes to your app's content rather than the document's default full-width body, you may need to explicitly set width: fit-content on your top-level container, for example body { width: fit-content; }
If your app imports @atlaskit/css-reset, be aware that it sets width: 100% on the body and html elements, overriding the width: fit-content recommendation above. To make sure your custom style takes effect, either:
!important to your inline styling, for example body { width: fit-content !important; }, or@atlaskit/css-reset before your own stylesheet so your styles take precedence:1 2import '@atlaskit/css-reset'; import './index.css';
Implementing a Custom UI modal requires two files:
index.js file in your app logicmy-modal-resource.js file
in the example belowindex.js
1 2import { Modal } from '@forge/bridge'; const modal = new Modal({ resource: 'my-modal-resource', onClose: (payload) => { console.log('onClose called with', payload); }, size: 'medium', context: { customKey: 'custom-value', }, title: 'My Modal', icon: './icon.png' }); modal.open();
my-modal-resource.js
1 2import { view } from '@forge/bridge'; const context = await view.getContext(); const customValue = context.extension.modal.customKey; view.close({ formValues: [], });
Rate this page: