API to render and manipulate extensions of type Modal.
1 2type ModalAction = { text: string; onClick: () => void; isDisabled?: boolean; isLoading?: boolean; testId?: string; }; type ModalCloseCallback = (e: MouseEvent) => boolean; type LifecycleCallback = (container: HTMLElement) => void; enum ModalAppearance { 'danger' = 'danger', 'warning' = 'warning', } enum ModalWidth { 'small' = 'small', 'medium' = 'medium', 'large' = 'large', 'x-large' = 'x-large', } interface ModalApi { setTitle: (title: string) => ModalApi; setWidth: (width: ModalWidth) => ModalApi; setAppearance: (appearance: ModalAppearance) => ModalApi; closeModal: () => ModalApi; onMount: (callback: LifecycleCallback) => ModalApi; onUnmount: (callback: LifecycleCallback) => ModalApi; setActions: (actions: ModalAction[]) => ModalApi; onClose: (callback: ModalCloseCallback) => ModalApi; }
Allows setting a title for the modal.
Name | Type | Description |
---|---|---|
title* | string | A string to serve as the title of the modal. |
* required
1 2import { ModalExtension } from '@atlassian/clientside-extensions'; /** * @clientside-extension * @extension-point reff.plugins-example-location */ export default ModalExtension.factory((extensionAPI, context) => { return { label: 'Open Modal', onAction(modalAPI) { modalAPI.setTitle('A cool modal with JS'); }, }; });
Allows specifying a width for the modal.
Name | Values |
---|---|
width* | "small" | "medium" | "large" | "x-large" |
Allows specifying an appearance for the modal.
Name | Values |
---|---|
appearance* | "danger" | "warning" |
When executed, it will close the modal.
Provides a container to render custom content as the body of the modal, and provides an API to interact with the modal once opened.
Name | Type | Description |
---|---|---|
container | HTMLElement | HTML element to be used as a container to render custom content in the body of the modal. |
Allows to specify the actions as buttons in the footer of the modal.
Name | Type | Description |
---|---|---|
actions* | ModalAction[] |
Actions for the modal. It supports the following properties: text: text content for the button. onClick: callback to execute when the button is clicked. isDisabled: if true, the button will be rendered in a disabled state. isLoading: if true, the button will be rendered in a loading state.
testId: a unique string that appears as a data attribute |
* required
Allows to be notified when the modal is about to be closed from an external action, like the user clicking away from the modal.
Name | Type | Description |
---|---|---|
callback | ModalCloseCallback | Callback that will get called before the modal is closed. If returning false, it will prevent the modal from close; otherwise, the modal will close. |
Allows to set a cleanup callback to be called when the modal container is about to be deleted.
Name | Type | Description |
---|---|---|
container | HTMLElement | HTML element that was provided to render custom content in it. It's important to unmount any React component you've mounted in there to avoid keeping the component alive when the container is destroyed. |
1 2import { ModalExtension } from '@atlassian/clientside-extensions'; import { getModalContent, confirm, primaryAction, secondaryAction } from './modal'; /** * @clientside-extension * @extension-point reff.plugins-example-location */ export default ModalExtension.factory((extensionAPI, context) => { return { label: 'Open Modal', onAction(modalAPI) { modalAPI.setTitle('A cool modal with JS'); modalAPI.setWidth('small'); modalAPI.setAppearance('warning'); modalAPI.onMount((container) => { // append your content for the modal container.innerHTML = getModalContent(); // set actions for the modal modalAPI.setActions([ { text: 'Primary', onClick: () => { primaryAction().then(() => { modalAPI.closeModal(); }); }, }, { text: 'Secondary', onClick: () => { container.innerHTML = getModalContent({ secondaryClicked: true }); }, }, ]); // listen when the modal is about to be closed by the user modalAPI.onClose(() => { return confirm('Are you sure you want to close this modal?'); }); }); }, }; });
Rate this page: