diff --git a/src/js/_enqueues/lib/admin-bar.js b/src/js/_enqueues/lib/admin-bar.js index eb18c61f8b5b8..7143fbd3d2429 100644 --- a/src/js/_enqueues/lib/admin-bar.js +++ b/src/js/_enqueues/lib/admin-bar.js @@ -108,8 +108,70 @@ if ( adminBarLogout ) { adminBarLogout.addEventListener( 'click', emptySessionStorage ); } + + // Toggle toolbar visibility with Ctrl+Shift+F keyboard shortcut (frontend only). + if ( ! document.body.classList.contains( 'wp-admin' ) ) { + document.addEventListener( 'keydown', function( event ) { + if ( event.which !== 70 || ! event.ctrlKey || ! event.shiftKey || event.altKey || event.metaKey ) { // Ctrl+Shift+F. + return; + } + + event.preventDefault(); + toggleToolbar( adminBar ); + } ); + } } ); + /** + * Toggle the toolbar visibility. + * + * Slides the toolbar out of view and adjusts page spacing by toggling + * the `wp-toolbar-hidden` class on the document element. + * + * @since TBD + * + * @param {HTMLElement} adminBar The admin bar element. + */ + function toggleToolbar( adminBar ) { + var isHidden = document.documentElement.classList.toggle( 'wp-toolbar-hidden' ); + + adminBar.setAttribute( 'aria-hidden', isHidden ? 'true' : 'false' ); + announceToolbarState( isHidden ); + } + + /** + * Announce toolbar visibility state to screen readers. + * + * @since TBD + * + * @param {boolean} isHidden Whether the toolbar is hidden. + */ + function announceToolbarState( isHidden ) { + var message = isHidden ? window.wpAdminBarL10n.toolbarHidden : window.wpAdminBarL10n.toolbarVisible, + el; + + if ( ! message ) { + return; + } + + el = document.getElementById( 'wp-toolbar-announce' ); + + if ( ! el ) { + el = document.createElement( 'div' ); + el.id = 'wp-toolbar-announce'; + el.className = 'screen-reader-text'; + el.setAttribute( 'role', 'status' ); + el.setAttribute( 'aria-live', 'polite' ); + document.body.appendChild( el ); + } + + // Clear then set to ensure screen readers re-announce. + el.textContent = ''; + setTimeout( function() { + el.textContent = message; + }, 100 ); + } + /** * Remove hover class for top level menu item when escape is pressed. * diff --git a/src/wp-includes/class-wp-admin-bar.php b/src/wp-includes/class-wp-admin-bar.php index 9e7b54823b900..c385b442e4143 100644 --- a/src/wp-includes/class-wp-admin-bar.php +++ b/src/wp-includes/class-wp-admin-bar.php @@ -72,6 +72,15 @@ public function initialize() { wp_enqueue_script( 'admin-bar' ); wp_enqueue_style( 'admin-bar' ); + wp_localize_script( + 'admin-bar', + 'wpAdminBarL10n', + array( + 'toolbarHidden' => __( 'Toolbar hidden.' ), + 'toolbarVisible' => __( 'Toolbar visible.' ), + ) + ); + /** * Fires after WP_Admin_Bar is initialized. * diff --git a/src/wp-includes/css/admin-bar.css b/src/wp-includes/css/admin-bar.css index 2331aeafd4b3c..844df49aea18c 100644 --- a/src/wp-includes/css/admin-bar.css +++ b/src/wp-includes/css/admin-bar.css @@ -99,6 +99,24 @@ html:lang(he-il) .rtl #wpadminbar * { background: #1d2327; /* Only visible in Windows High Contrast mode */ outline: 1px solid transparent; + transition: transform 0.2s ease-in-out, visibility 0.2s ease-in-out; +} + +/** + * Toolbar toggle hidden state. + * + * Toggled via Ctrl+Shift+F keyboard shortcut on the frontend. + * Sets the admin bar height variable to 0 so all dependent spacing + * (scroll-padding, bump margin) adjusts automatically. + */ +html.wp-toolbar-hidden { + --wp-admin--admin-bar--height: 0px; + margin-top: 0 !important; +} + +html.wp-toolbar-hidden #wpadminbar { + transform: translateY(-100%); + visibility: hidden; } #wpadminbar .ab-sub-wrapper,