Breaking: #107443 - Migrate Modal component from Bootstrap to native dialog
See forge#107443
Description
The TYPO3 Modal component has been migrated from Bootstrap's modal implementation
to use the native HTML
<dialog> element. This change improves accessibility,
reduces bundle size, and eliminates dependency on Bootstrap's JavaScript for modal
functionality.
As part of this migration, Bootstrap's native modal events (such as
show.,
shown.,
hide., and
hidden.) are no longer dispatched. Additionally, direct Bootstrap
modal API usage (such as
new Modal from Bootstrap or
$)
is no longer supported.
Impact
Bootstrap modal events (
*.) are no longer available. Extensions that
listen to these events must migrate to TYPO3's custom modal events.
The modal now uses the native
<dialog> element with updated CSS classes and
structure. Direct manipulation of Bootstrap modal APIs will no longer work.
Extensions using
data-,
data- or
data- attributes to trigger modals will need to migrate to
TYPO3's Modal API.
Affected installations
All installations with custom extensions that:
- Listen to Bootstrap modal events (
show.,bs. modal shown.,bs. modal hide.,bs. modal hidden.)bs. modal - Use Bootstrap's modal JavaScript API directly (
new bootstrap.)Modal () - Use jQuery to control modals (
$)(element). modal ('show') - Use
data-attributes to trigger modalsbs- toggle="modal" - Use
data-attributes to set modal contentsbs- content="..." - Manipulate modal DOM structure or classes expecting Bootstrap's markup
Migration
Event Migration
Replace Bootstrap modal event listeners with TYPO3's custom modal events. Note that event listeners must be attached to the modal instance returned by the Modal API, not queried from the DOM:
Before:
const modalElement = document.querySelector('.modal');
modalElement.addEventListener('show.bs.modal', (event) => {
console.log('Modal is about to be shown');
});
modalElement.addEventListener('shown.bs.modal', (event) => {
console.log('Modal is now visible');
});
modalElement.addEventListener('hide.bs.modal', (event) => {
console.log('Modal is about to be hidden');
});
modalElement.addEventListener('hidden.bs.modal', (event) => {
console.log('Modal is now hidden');
});
After:
import Modal from '@typo3/backend/modal';
import Severity from '@typo3/backend/severity';
const modal = Modal.show(
'My Modal Title',
'This is the modal content',
Severity.info
);
// Attach event listeners to the modal instance
modal.addEventListener('typo3-modal-show', (event) => {
console.log('Modal is about to be shown');
});
modal.addEventListener('typo3-modal-shown', (event) => {
console.log('Modal is now visible');
});
modal.addEventListener('typo3-modal-hide', (event) => {
console.log('Modal is about to be hidden');
});
modal.addEventListener('typo3-modal-hidden', (event) => {
console.log('Modal is now hidden');
});
Bootstrap API Migration
Replace Bootstrap modal API calls with TYPO3's Modal API. Do not attempt to instantiate Bootstrap modals directly or manipulate modal DOM elements.
Before:
import { Modal } from 'bootstrap';
const modalElement = document.querySelector('.modal');
const bsModal = new Modal(modalElement);
bsModal.show();
bsModal.hide();
After:
import Modal from '@typo3/backend/modal';
import Severity from '@typo3/backend/severity';
// Show a simple modal
Modal.show(
'My Modal Title',
'This is the modal content',
Severity.info,
[
{
text: 'Close',
btnClass: 'btn-default',
trigger: (event, modal) => modal.hideModal()
}
]
);
// Dismiss the current modal
Modal.dismiss();
Data Attribute Migration
Replace Bootstrap's
data- and
data- attributes with
TYPO3's Modal trigger API:
Before:
<button type="button"
data-bs-toggle="modal"
data-bs-target="#myModal"
data-bs-content="Are you sure?">
Open Modal
</button>
After:
<button type="button"
class="t3js-modal-trigger"
data-title="Confirmation"
data-content="Are you sure?"
data-severity="warning"
data-button-close-text="Cancel"
data-button-ok-text="Confirm">
Open Modal
</button>
Or use the JavaScript API directly:
import Modal from '@typo3/backend/modal';
document.querySelector('button').addEventListener('click', (event) => {
Modal.confirm(
'Confirmation',
'Are you sure?',
Severity.warning
);
});