diff --git a/admin_toolbar.libraries.yml b/admin_toolbar.libraries.yml index 7bfd19767d33f0ae92d63cedc92261e4a2d61dc1..6bf7020dbf30687a340241463ea7be3623596bf5 100644 --- a/admin_toolbar.libraries.yml +++ b/admin_toolbar.libraries.yml @@ -26,6 +26,11 @@ toolbar.disable_sticky: css: theme: css/admin_toolbar.disable_sticky.css: {} + js: + js/admin_toolbar.disable_sticky.js: {} + dependencies: + - admin_toolbar/toolbar.tree + - core/drupal.displace # Enable toolbar custom sticky behavior. toolbar.sticky_behavior: @@ -36,6 +41,7 @@ toolbar.sticky_behavior: js/admin_toolbar.sticky_behavior.js: {} dependencies: - admin_toolbar/toolbar.tree + - core/drupal.displace # Enable toolbar toggle keyboard shortcut. toolbar.toggle_shortcut: @@ -47,3 +53,4 @@ toolbar.toggle_shortcut: js/admin_toolbar.toggle_shortcut.js: {} dependencies: - admin_toolbar/toolbar.tree + - core/drupal.displace diff --git a/js/admin_toolbar.disable_sticky.js b/js/admin_toolbar.disable_sticky.js new file mode 100644 index 0000000000000000000000000000000000000000..c01ace85bd4e6f2ac12bdc864e615fd72b7d8170 --- /dev/null +++ b/js/admin_toolbar.disable_sticky.js @@ -0,0 +1,45 @@ +/** + * @file + * Admin Toolbar disable sticky behavior JS. + */ + +(($, Drupal, once) => { + /** + * Implements the Admin Toolbar configured 'disabled sticky behavior'. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches the behavior to remove reset top offset. + */ + Drupal.behaviors.adminToolbarDisableStickyBehavior = { + attach (context) { + if (context !== document) { + return; + } + // If toolbar 'stickyness' is disabled, the toolbar should not be + // included in the calculation of the top offset. Listen for the offset + // change event and remove data-offset-top attributes from toolbar-bar + // and any active toolbar-tray. + once('admin-toolbar-disable-sticky', 'body', context).forEach(() => { + $(document).on( + `drupalViewportOffsetChange`, + () => { + document.getElementById('toolbar-bar') + .removeAttribute('data-offset-top'); + + document.querySelector('.toolbar-tray.is-active') + ?.removeAttribute('data-offset-top'); + + // Trigger a recalculation of viewport displacing elements. + // Use setTimeout to ensure this recalculation happens after + // changes to visual elements have processed. + setTimeout(() => { + Drupal.displace(false); + }, "500"); + }, + ); + }); + }, + }; +})(jQuery, Drupal, once); diff --git a/js/admin_toolbar.sticky_behavior.js b/js/admin_toolbar.sticky_behavior.js index 569aedcf8771187f3ba64005be9859ba9d62a4e0..f5b847261f9dd0db499777aec74a666b884277f7 100644 --- a/js/admin_toolbar.sticky_behavior.js +++ b/js/admin_toolbar.sticky_behavior.js @@ -54,6 +54,10 @@ element.classList.remove('sticky-toolbar-hidden'); } lastScrollTop = scrollTop; + + // Recalculate displacement offsets '--drupal-displace-offset-top' + // after the toolbar visibility changes to ensure correct layout. + Drupal.displace(); }); }, ); diff --git a/js/admin_toolbar.toggle_shortcut.js b/js/admin_toolbar.toggle_shortcut.js index ba2141f68410d7237ea6869403256a47651f9f2c..f2b4974c1e064ab181661b93cbc45574b5a4ed01 100644 --- a/js/admin_toolbar.toggle_shortcut.js +++ b/js/admin_toolbar.toggle_shortcut.js @@ -97,11 +97,19 @@ elementClassList.add('sticky-toolbar-hidden'); elementClassList.add('toggle-toolbar-hidden'); } + // Set the new state of the toolbar in local storage. localStorage.setItem( 'Drupal.adminToolbar.toggleToolbarHidden', !toolbarHidden, ); + + // Trigger a recalculation of viewport displacing elements. Use setTimeout + // to ensure this recalculation happens after changes to visual elements + // have processed. + setTimeout(() => { + Drupal.displace(); + }, "500"); }, };