diff --git a/README.md b/README.md index f72fc2ca53ab017cef4478ac2826a5f88beafe97..a43277737ef67c2888ad135b80dad9566a3117c5 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,6 @@ views, blocks...). See the [docs](./docs) folder for more detailed documentation on: - [details element](./docs/Details.md) - [form API](./docs/Forms.md) -- [modal](./docs/Modal.md) - [what is out of scope](./docs/Out-of-scope.md) diff --git a/assets/js/misc/dialog/dialog.ajax.js b/assets/js/misc/dialog/dialog.ajax.js deleted file mode 100644 index ec16268d83ed61bba3baf80aef6438d19a78f948..0000000000000000000000000000000000000000 --- a/assets/js/misc/dialog/dialog.ajax.js +++ /dev/null @@ -1,240 +0,0 @@ -/** - * @file - * Extends the Drupal AJAX functionality to integrate the dialog API. - */ - -(($, Drupal) => { - /** - * Initialize dialogs for Ajax purposes. - * - * @type {Drupal~behavior} - * - * @prop {Drupal~behaviorAttach} attach - * Attaches the behaviors for dialog ajax functionality. - */ - Drupal.behaviors.dialog = { - attach: function attach(context, settings) { - const $context = $(context); - - if (!$('#drupal-modal').length) { - $( - `<div id="drupal-modal" class="modal fade" tabindex="-1" role="dialog"> - <div class="modal-dialog" role="document"> - <div class="modal-content"></div> - </div> - </div>`, - ) - .hide() - .appendTo('body'); - } - - const $dialog = $context.closest('.modal-content'); - if ($dialog.length) { - const dialogSettings = $dialog.closest('.modal').data('settings'); - if (dialogSettings && dialogSettings.drupalAutoButtons) { - $dialog.trigger('dialogButtonsChange'); - } - } - - const originalClose = settings.dialog.close; - - settings.dialog.close = (event) => { - for ( - // eslint-disable-next-line - var _len = arguments.length, - args = Array(_len > 1 ? _len - 1 : 0), - _key = 1; - _key < _len; - _key++ - ) { - // eslint-disable-next-line - args[_key - 1] = arguments[_key]; - } - - // eslint-disable-next-line - originalClose.apply(settings.dialog, [event].concat(args)); - $(event.target).remove(); - }; - }, - prepareDialogButtons: function prepareDialogButtons($dialog) { - const buttons = []; - const $buttons = $dialog.find( - '.form-actions input[type=submit], .form-actions button[type=submit], .form-actions a.button', - ); - // eslint-disable-next-line func-names - $buttons.each(function () { - const $originalButton = $(this); - this.style.display = 'none'; - buttons.push({ - text: $originalButton.html() || $originalButton.attr('value'), - class: $originalButton.attr('class'), - click: function click(e) { - if ($originalButton[0].tagName === 'A') { - $originalButton[0].click(); - } else { - $originalButton - .trigger('mousedown') - .trigger('mouseup') - .trigger('click'); - e.preventDefault(); - } - }, - }); - }); - return buttons; - }, - }; - - // eslint-disable-next-line - Drupal.AjaxCommands.prototype.openDialogByUrl = (ajax, response, status) => { - const settings = $.extend(response.settings, {}); - - const elementSettings = { - progress: { - type: 'throbber', - }, - dialogType: '_modal', - dialog: response.dialogOptions, - url: settings.url, - }; - - const dialogUrlAjax = Drupal.ajax(elementSettings); - dialogUrlAjax.execute(); - }; - - Drupal.AjaxCommands.prototype.coreOpenDialog = - Drupal.AjaxCommands.prototype.openDialog; - - Drupal.AjaxCommands.prototype.openDialog = (ajax, response, status) => { - if (ajax.dialogRenderer === 'off_canvas') { - return Drupal.AjaxCommands.prototype.coreOpenDialog( - ajax, - response, - status, - ); - } - - if (!response.selector) { - return false; - } - let $dialog = $(response.selector); - if (!$dialog.length) { - $dialog = $( - `<div id="${response.selector.replace( - /^#/, - '', - )}" class="modal fade" tabindex="-1" role="dialog"> - <div class="modal-dialog" role="document"> - <div class="modal-content"></div> - </div> - </div>`, - ) - .hide() - .appendTo('body'); - } - - if (!ajax.wrapper) { - response.selector = `${response.selector.toString()} .modal-content`; - } - - response.command = 'insert'; - response.method = 'html'; - response.dialogOptions = response.dialogOptions || {}; - - // Do some extra things here, set Drupal.autocomplete options to render - // autocomplete box inside the modal. - if ( - Drupal.autocomplete !== undefined && - Drupal.autocomplete.options !== undefined - ) { - Drupal.autocomplete.options.appendTo = response.selector; - } - if ( - response.dialogOptions.modalDialogWrapBody === undefined || - response.dialogOptions.modalDialogWrapBody === true || - response.dialogOptions.modalDialogWrapBody === 'true' - ) { - response.data = `<div class="modal-body">${response.data}</div>`; - } - ajax.commands.insert(ajax, response, status); - - // Move the buttons to the Bootstrap dialog buttons area. - if (typeof response.dialogOptions.drupalAutoButtons === 'undefined') { - response.dialogOptions.drupalAutoButtons = true; - } else if (response.dialogOptions.drupalAutoButtons === 'false') { - response.dialogOptions.drupalAutoButtons = false; - } else { - response.dialogOptions.drupalAutoButtons = - !!response.dialogOptions.drupalAutoButtons; - } - if ( - !response.dialogOptions.buttons && - response.dialogOptions.drupalAutoButtons - ) { - response.dialogOptions.buttons = - Drupal.behaviors.dialog.prepareDialogButtons($dialog); - } - - // Bind dialogButtonsChange. - $dialog.on('dialogButtonsChange', () => { - const buttons = Drupal.behaviors.dialog.prepareDialogButtons($dialog); - const dialog = Drupal.uiSuiteDialog($dialog.get(0)); - dialog.updateButtons(buttons); - }); - - // Open the dialog itself. - response.dialogOptions = response.dialogOptions || {}; - const dialog = Drupal.uiSuiteDialog($dialog.get(0), response.dialogOptions); - if (response.dialogOptions.modal) { - dialog.showModal(); - } else { - dialog.show(); - } - - // Add the standard Drupal class for buttons for style consistency. - $dialog.parent().find('.ui-dialog-buttonset').addClass('form-actions'); - }; - - // eslint-disable-next-line - Drupal.AjaxCommands.prototype.closeDialog = (ajax, response, status) => { - const $dialog = $(response.selector); - if ($dialog.length) { - Drupal.uiSuiteDialog($dialog.get(0)).close(); - } - - $dialog.off('dialogButtonsChange'); - }; - - // eslint-disable-next-line - Drupal.AjaxCommands.prototype.setDialogOption = (ajax, response, status) => { - const $dialog = $(response.selector); - if ($dialog.length) { - $dialog.dialog('option', response.optionName, response.optionValue); - } - }; - - // eslint-disable-next-line - $(window).on("dialog:aftercreate", (e, dialog, $element, settings) => { - // eslint-disable-next-line - $element.on("click.dialog", ".dialog-cancel", (e) => { - dialog.close('cancel'); - e.preventDefault(); - e.stopPropagation(); - }); - }); - - $(window).on('dialog:beforeclose', (e, dialog, $element) => { - $element.off('.dialog'); - - // Do some extra things here, set Drupal.autocomplete options to render - // autocomplete box inside the modal. - if ( - Drupal.autocomplete !== undefined && - Drupal.autocomplete.options !== undefined - ) { - if (Drupal.autocomplete.options.appendTo !== undefined) { - delete Drupal.autocomplete.options.appendTo; - } - } - }); -})(jQuery, Drupal); diff --git a/assets/js/misc/dialog/dialog.js b/assets/js/misc/dialog/dialog.js deleted file mode 100644 index ca7e6c00d7ea40e11cfb1d379cdb6a33f780c477..0000000000000000000000000000000000000000 --- a/assets/js/misc/dialog/dialog.js +++ /dev/null @@ -1,226 +0,0 @@ -/** - * @file - * Dialog API inspired by HTML5 dialog element. - * - * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/commands.html#the-dialog-element - */ - -(($, Drupal, drupalSettings) => { - /** - * Default dialog options. - * - * @type {object} - * - * @prop {bool} [autoOpen=true] - * @prop {bool} [backdrop=undefined] - * @prop {string} [buttonClass='btn'] - * @prop {string} [buttonPrimaryClass='btn-primary'] - * @prop {function} close - * @prop {string} [dialogClasses=''] - * @prop {string} [dialogHeadingLevel=5] - * @prop {string} [dialogShowHeader=true] - * @prop {string} [dialogShowHeaderTitle=true] - * @prop {string} [dialogStatic=false] - * @prop {bool} [drupalAutoButtons=undefined] - * @prop {string} [title=undefined] - * @prop {string} [width=undefined] - */ - drupalSettings.dialog = { - autoOpen: true, - backdrop: undefined, - buttonClass: 'btn', - buttonPrimaryClass: 'btn-primary', - close: function close(event) { - Drupal.uiSuiteDialog(event.target).close(); - Drupal.detachBehaviors(event.target, null, 'unload'); - }, - dialogClasses: '', - dialogHeadingLevel: 5, - dialogShowHeader: true, - dialogShowHeaderTitle: true, - dialogStatic: false, - drupalAutoButtons: undefined, - title: undefined, - width: undefined, - }; - - /** - * @typedef {object} Drupal.dialog~dialogDefinition - * - * @prop {boolean} open - * Is the dialog open or not. - * @prop {*} returnValue - * Return value of the dialog. - * @prop {function} show - * Method to display the dialog on the page. - * @prop {function} showModal - * Method to display the dialog as a modal on the page. - * @prop {function} close - * Method to hide the dialog from the page. - */ - - /** - * Polyfill HTML5 dialog element with jQueryUI. - * - * @param {HTMLElement} element - * The element that holds the dialog. - * @param {object} options - * jQuery UI options to be passed to the dialog. - * - * @return {Drupal.dialog~dialogDefinition} - * The dialog instance. - */ - Drupal.uiSuiteDialog = (element, options) => { - let undef; - - const $element = $(element); - const domElement = $element.get(0); - - const dialog = { - open: false, - returnValue: undef, - }; - - options = $.extend({}, drupalSettings.dialog, options); - - function settingIsTrue(setting) { - return setting !== undefined && (setting === true || setting === 'true'); - } - - function updateButtons(buttons) { - const modalFooter = $('<div class="modal-footer">'); - // eslint-disable-next-line func-names - $.each(buttons, function () { - const buttonObject = this; - const classes = [options.buttonClass, options.buttonPrimaryClass]; - - const button = $('<button type="button">'); - if (buttonObject.attributes !== undefined) { - $(button).attr(buttonObject.attributes); - } - $(button) - .addClass(buttonObject.class) - .click((e) => { - if (buttonObject.click !== undefined) { - buttonObject.click(e); - } - }) - .html(buttonObject.text); - - if ( - $(button).attr('class') && - !$(button) - .attr('class') - .match(/\bbtn-.*/) - ) { - $(button).addClass(classes.join(' ')); - } - - $(modalFooter).append(button); - }); - if ( - $('.modal-dialog .modal-content .modal-footer', $element).length > 0 - ) { - $('.modal-dialog .modal-content .modal-footer', $element).remove(); - } - if ($(modalFooter).html().length > 0) { - $(modalFooter).appendTo($('.modal-dialog .modal-content', $element)); - } - } - - function openDialog(settings) { - settings = $.extend({}, options, settings); - - // eslint-disable-next-line no-undef - const event = new DrupalDialogEvent('beforecreate', dialog, settings); - domElement.dispatchEvent(event); - dialog.open = true; - settings = event.settings; - - if (settings.dialogClasses !== undefined) { - $('.modal-dialog', $element) - .removeAttr('class') - .addClass('modal-dialog') - .addClass(settings.dialogClasses); - } - - // The modal dialog header. - if (settingIsTrue(settings.dialogShowHeader)) { - let modalHeader = '<div class="modal-header">'; - const heading = settings.dialogHeadingLevel; - - if (settingIsTrue(settings.dialogShowHeaderTitle)) { - modalHeader += `<h${heading} class="modal-title">${settings.title}</h${heading}>`; - } - - // @todo use the pattern button_close directly if possible in JS. - modalHeader += `<button type="button" class="close btn-close" data-bs-dismiss="modal" data-dismiss="modal" aria-label="${Drupal.t( - 'Close', - )}"></button></div>`; - - $(modalHeader).prependTo($('.modal-dialog .modal-content', $element)); - } - - if (settingIsTrue(settings.dialogStatic)) { - $element.attr('data-bs-backdrop', 'static'); - $element.attr('data-bs-keyboard', 'false'); - } - - if ( - settingIsTrue(settings.drupalAutoButtons) && - settings.buttons.length > 0 - ) { - updateButtons(settings.buttons); - } - - if ($element.modal !== undefined) { - $element.modal(settings); - $element.modal('show'); - } - - if (settings.width) { - const $dialog = $('.modal-dialog', $element); - $dialog[0].style.maxWidth = settings.width; - } - - domElement.dispatchEvent( - // eslint-disable-next-line no-undef - new DrupalDialogEvent('aftercreate', dialog, settings), - ); - } - - function closeDialog(value) { - if ($element.modal !== undefined) { - $element.modal('hide'); - } - dialog.returnValue = value; - dialog.open = false; - } - - dialog.updateButtons = (buttons) => { - updateButtons(buttons); - }; - - dialog.show = () => { - openDialog({ backdrop: false }); - }; - dialog.showModal = () => { - openDialog({ backdrop: true }); - }; - dialog.close = () => { - closeDialog({}); - }; - - $element.on('hide.bs.modal', () => { - // eslint-disable-next-line no-undef - domElement.dispatchEvent(new DrupalDialogEvent('beforeclose', dialog)); - }); - - $element.on('hidden.bs.modal', () => { - // eslint-disable-next-line no-undef - domElement.dispatchEvent(new DrupalDialogEvent('afterclose', dialog)); - }); - - return dialog; - }; -})(jQuery, Drupal, drupalSettings); diff --git a/docs/Modal.md b/docs/Modal.md deleted file mode 100644 index 0ff8a5c56dd1e2268a1207c5a9c6255ab10f45fa..0000000000000000000000000000000000000000 --- a/docs/Modal.md +++ /dev/null @@ -1,42 +0,0 @@ -# Modal - -UI Suite Bootstrap replaces the Drupal core modal to provide Bootstrap's one. - - -## Example - -Here is an example to create a modal opening link with some customized options: - -```php -$modal_options = [ - 'dialogClasses' => 'modal-dialog-centered', - 'dialogShowHeader' => 'false', -]; - -$build['modal_link'] = [ - '#type' => 'link', - '#title' => $this->t('Link title'), - '#url' => Url::fromRoute('my_route'), - '#attributes' => [ - 'class' => ['use-ajax'], - 'data-dialog-type' => 'modal', - 'data-dialog-options' => Json::encode($modal_options), - ], -]; -``` - - -## Options - -The list of options as well as there default value can be found in -[dialog.js](../assets/js/misc/dialog/dialog.es6.js) (`drupalSettings.dialog`). - -| Option | Type | Default value | Description | -|-----------------------|---------|---------------|------------------------------------------------------------------------------| -| dialogClasses | string | (empty) | | -| dialogShowHeader | boolean | true | | -| dialogShowHeaderTitle | boolean | true | | -| dialogStatic | boolean | false | | -| dialogHeadingLevel | integer | 5 | | -| buttonClass | string | btn | | -| buttonPrimaryClass | string | btn-primary | Will only have an impact if the button does not already have a `btn-` class. | diff --git a/ui_suite_bootstrap.info.yml b/ui_suite_bootstrap.info.yml index 8f48682dcd1c640637fa9df3df153081f7ceda4a..99bf9f060ac8522195eea6cc36be1e699656fb2e 100644 --- a/ui_suite_bootstrap.info.yml +++ b/ui_suite_bootstrap.info.yml @@ -46,12 +46,6 @@ libraries-extend: - ui_suite_bootstrap/drupal.ajax core/drupal.checkbox: - ui_suite_bootstrap/drupal.checkbox - core/drupal.dialog: - - ui_suite_bootstrap/drupal.dialog - # core/drupal.dialog: - # - ui_suite_bootstrap/drupal.dialog - # core/drupal.dialog.ajax: - # - ui_suite_bootstrap/drupal.dialog.ajax core/drupal.message: - ui_suite_bootstrap/drupal.message core/drupal.progress: diff --git a/ui_suite_bootstrap.libraries.yml b/ui_suite_bootstrap.libraries.yml index 3d468505f203a90ae628f0a0726c83d5ba307b75..e9afe880a8c88d063e78aa1bb5b0466976d08b9f 100644 --- a/ui_suite_bootstrap.libraries.yml +++ b/ui_suite_bootstrap.libraries.yml @@ -35,22 +35,6 @@ drupal.checkbox: dependencies: - core/drupal -drupal.dialog: - js: - assets/js/misc/dialog/dialog.js: {} - dependencies: - - core/jquery - - core/drupal - - core/drupalSettings - -drupal.dialog.ajax: - js: - assets/js/misc/dialog/dialog.ajax.js: {} - dependencies: - - core/jquery - - core/drupal - - core/drupal.ajax - drupal.dialog.off_canvas: css: component: