This is a continuation of the work started in 4. Custom HTML content.
Modals can be complicated to create since generally you'll need to use an external library, and then modify its design to match the product you're creating the modals for.
With Client-side Extensions (CSE), you can use an extension type called Modal that lets you create a modal dialog that works well with your product, and you can focus on your feature instead.
To create the modal extension, you need to use the ModalExtension
factory. The CSE runtime will then use the onAction
method
to inject a Modal API object when the modal is ready for you
to render the content in.
Remember that the onAction
method behaves differently for each extension type. For more info, see extension API reference.
The modal API has the same onMount
/onUnmount
methods as panels to render your content, but also has some modal specific methods.
One of the modal specific APIs is setTitle
that allows you to specify a title in the modal header.
You're now going to create a modal extension that opens after clicking a button in the pull request diff
toolbar.
In the /src/my-app/extensions/first-extension.js
file:
diff
toolbar extension point: bitbucket.ui.pullrequest.diff.toolbar
.ModalExtension
from @atlassian/clientside-extensions
, and use its factory to create a modal extension.onAction
to get a modal API object.1 2// #/src/my-app/extensions/first-extension.js import { ModalExtension } from '@atlassian/clientside-extensions'; /** * @clientside-extension * @extension-point bitbucket.ui.pullrequest.diff.toolbar */ export default ModalExtension.factory((extensionAPI, context) => { return { label: 'Click to open a modal', onAction: (modalAPI) => { const getContent = () => ` <p>And some content inside the modal too.</p> `; modalAPI.setTitle('Look, a Modal!'); modalAPI.onMount((container) => { container.innerHTML = getContent(); }); modalAPI.onUnmount((container) => { container.innerHTML = ''; }); }, }; });
The modal API provides a method called setActions
that allows you to render action buttons in your modal footer, and execute
arbitrary JavaScript when they are clicked.
You can also close the modal after executing an action by using closeModal
.
Modify your modal extension to have a pair of actions. One of them should modify your modal content, and the other close the modal when clicked.
In the /src/my-app/extensions/first-extension.js
file:
setActions
.1 2// #/src/my-app/extensions/first-extension.js import { ModalExtension } from '@atlassian/clientside-extensions'; /** * @clientside-extension * @extension-point bitbucket.ui.pullrequest.diff.toolbar */ export default ModalExtension.factory((extensionAPI, context) => { return { label: 'Click to open a modal', onAction: (modalAPI) => { let count = 0; const getContent = () => ` <p>The primary button has been clicked ${count} times.</p> `; modalAPI.setTitle('Look, a Modal!'); modalAPI.onMount((container) => { container.innerHTML = getContent(); // setting the actions of the modal modalAPI.setActions([ { text: 'Primary', onClick: () => { count++; container.innerHTML = getContent(); }, }, { text: 'Close', onClick: () => modalAPI.closeModal(), }, ]); }); modalAPI.onUnmount((container) => { container.innerHTML = ''; }); }, }; });
Client-side Extensions (CSE) provides a utility that makes it easier to use React with the Modal extension. For more info, see Rendering elements as React.
You've learned:
Make sure to check the modal API reference to explore more things you can do with modals.
Rate this page: