Breaking: #98288 - Updated Backend Modal API

See forge#98288

Description

The modal API provided by the module @typo3/backend/modal.js has been adapted to backed by a custom web component and therefore gained an updated, stateless interface.

The return type of all Modal.* factory methods has been changed from JQuery to ModalElement.

ModalElement is a web component which allows to attach modal API (like modal hiding) directly to the returned object. Usage of globals like Modal.currentModal can thus be avoided when using the returned ModalElement.

This affects the following methods which now return ModalElement:

  • Modal.confirm()

  • Modal.loadUrl()

  • Modal.show()

  • Modal.advanced()

  • Modal.setButtons()

  • Modal.generate()

Furthermore the following changes have been applied:

  • The Button property dataAttributes has been removed without replacement, as the functionality can be expressed via Button.name or Button.trigger and is therefore redundant.

  • The ajaxTarget of the modal Configuration object has been dropped, as it was never actually used in TYPO3. Use nested, custom web components for dynamic ajax loading of modal sub areas.

  • The rendering life cycle has been adapted to synchronize rendering to the browsers idle callback. That means rendering is delayed and modal content can not be modified directly after modal creation. The existing API Configuration.callback has to be used instead, but usage of lit TemplateResult without the need for post-processing is suggested to be used instead.

  • The bs.modal.* events are no longer considered API, but remain working for the time being (as bootstrap modal is still used right now). These events may be dropped at any time, when the modal component is switched to shadow dom, or the native <dialog> tag. Therefore typo3-modal-* events are to be used instead.

  • The event modal-destroyed has been removed. Use typo3-modal-hide or typo3-modal-hidden instead.

  • Modal.currentModal.trigger('modal-dismiss') has been removed. Use ModalElement.hideModal() instead.

Impact

Using jQuery API on ModalElement will lead to JavaScript errors as no jQuery interop is provided.

Affected installations

All 3rd party extensions using the API of the @typo3/backend/modal.js module are affected, if they use the return type of the methods to attach to events or to customize the modal after creations.

Migration

Given the following fully-fledged example of a modal that uses custom buttons, with custom attributes, triggers and events, they should be migrated away from JQuery to ModalElement usage.

Existing code:

var configuration = {
   buttons: [
      {
         text: 'Save changes',
         name: 'save',
         icon: 'actions-document-save',
         active: true,
         btnClass: 'btn-primary',
         dataAttributes: {
            action: 'save'
         },
         trigger: function() {
            Modal.currentModal.trigger('modal-dismiss');
         }
      }
   ]
};
Modal
  .advanced(configuration)
  .on('hidden.bs.modal', function() {
    // do something
  });

Should be adapted to:

const modal = Modal.advanced({
   buttons: [
      {
         text: 'Save changes',
         name: 'save',
         icon: 'actions-document-save',
         active: true,
         btnClass: 'btn-primary',
         trigger: function(event, modal) {
           modal.hideModal();
         }
      }
   ]
});
modal.addEventListener('typo3-modal-hidden', function() {
  // do something
});