From fb107a4573de06cd52b38ceea7ef7aacb10fce62 Mon Sep 17 00:00:00 2001
From: Poli Gilad <83961704+poligilad-auto@users.noreply.github.com>
Date: Mon, 15 Jun 2026 14:12:03 +0200
Subject: [PATCH 1/3] Administration: Add box reordering toggle to Screen
Options.
---
src/js/_enqueues/admin/common.js | 1 +
src/js/_enqueues/admin/postbox.js | 99 +++++++++++++++++++
src/wp-admin/admin-ajax.php | 1 +
src/wp-admin/admin-header.php | 2 +
src/wp-admin/css/common.css | 17 ++++
src/wp-admin/css/dashboard.css | 4 +
src/wp-admin/includes/ajax-actions.php | 19 ++++
src/wp-admin/includes/class-wp-screen.php | 73 ++++++++++++--
src/wp-admin/includes/screen.php | 13 +++
tests/phpunit/includes/testcase-ajax.php | 1 +
tests/phpunit/tests/admin/includesScreen.php | 35 +++++++
.../tests/ajax/wpAjaxMetaBoxReordering.php | 55 +++++++++++
12 files changed, 313 insertions(+), 7 deletions(-)
create mode 100644 tests/phpunit/tests/ajax/wpAjaxMetaBoxReordering.php
diff --git a/src/js/_enqueues/admin/common.js b/src/js/_enqueues/admin/common.js
index c3d49310e8897..93fd8d686a63c 100644
--- a/src/js/_enqueues/admin/common.js
+++ b/src/js/_enqueues/admin/common.js
@@ -1859,6 +1859,7 @@ $( function() {
var width = navigator.userAgent.indexOf('AppleWebKit/') > -1 ? $window.width() : window.innerWidth;
if (
+ $body.hasClass( 'meta-box-reordering-disabled' ) ||
( width <= 782 ) ||
( 1 >= $sortables.find( '.ui-sortable-handle:visible' ).length && jQuery( '.columns-prefs-1 input' ).prop( 'checked' ) )
) {
diff --git a/src/js/_enqueues/admin/postbox.js b/src/js/_enqueues/admin/postbox.js
index b6d1b6569dc84..d0173134c9d0d 100644
--- a/src/js/_enqueues/admin/postbox.js
+++ b/src/js/_enqueues/admin/postbox.js
@@ -104,6 +104,10 @@
postboxWithinSortablesIndex = postboxesWithinSortables.index( postbox ),
firstOrLastPositionMessage;
+ if ( ! postboxes.metaBoxReorderingEnabled ) {
+ return;
+ }
+
if ( 'dashboard_browser_nag' === postboxId ) {
return;
}
@@ -344,6 +348,13 @@
postboxes.save_order( page );
}
});
+
+ $( '.meta-box-reordering-toggle' ).on( 'click.postboxes', function() {
+ var enabled = $( this ).prop( 'checked' );
+
+ postboxes.setMetaBoxReordering( enabled );
+ postboxes.save_meta_box_reordering_state( enabled );
+ } );
},
/**
@@ -419,6 +430,8 @@
}
});
+ this.setMetaBoxReordering( this.isMetaBoxReorderingEnabled() );
+
if ( isMobile ) {
$(document.body).on('orientationchange.postboxes', function(){ postboxes._pb_change(); });
this._pb_change();
@@ -437,6 +450,68 @@
});
},
+ /**
+ * Checks whether meta box reordering is enabled.
+ *
+ * @since 7.1.0
+ *
+ * @return {boolean} Whether meta box reordering is enabled.
+ */
+ isMetaBoxReorderingEnabled: function() {
+ var $toggle = $( '#meta-box-reordering' );
+
+ if ( $toggle.length ) {
+ return $toggle.prop( 'checked' );
+ }
+
+ return ! $( document.body ).hasClass( 'meta-box-reordering-disabled' );
+ },
+
+ /**
+ * Enables or disables the meta box reordering UI.
+ *
+ * @since 7.1.0
+ *
+ * @param {boolean} enabled Whether reordering should be enabled.
+ * @return {void}
+ */
+ setMetaBoxReordering: function( enabled ) {
+ var $body = $( document.body ),
+ $orderButtons = $( '.postbox .handle-order-higher, .postbox .handle-order-lower' );
+
+ this.metaBoxReorderingEnabled = !! enabled;
+
+ $body
+ .toggleClass( 'meta-box-reordering-enabled', this.metaBoxReorderingEnabled )
+ .toggleClass( 'meta-box-reordering-disabled', ! this.metaBoxReorderingEnabled );
+
+ if ( this.metaBoxReorderingEnabled ) {
+ $orderButtons
+ .prop( 'disabled', false )
+ .removeAttr( 'tabindex aria-hidden' );
+ this.updateOrderButtonsProperties();
+ } else {
+ $orderButtons
+ .prop( 'disabled', true )
+ .attr( {
+ 'aria-hidden': 'true',
+ tabindex: '-1'
+ } );
+ }
+
+ if ( window.wpResponsive && window.wpResponsive.maybeDisableSortables ) {
+ window.wpResponsive.maybeDisableSortables();
+ return;
+ }
+
+ try {
+ $( '.meta-box-sortables' )
+ .sortable( this.metaBoxReorderingEnabled ? 'enable' : 'disable' )
+ .find( '.ui-sortable-handle' )
+ .toggleClass( 'is-non-sortable', ! this.metaBoxReorderingEnabled );
+ } catch ( e ) {}
+ },
+
/**
* Saves the state of the postboxes to the server.
*
@@ -476,6 +551,30 @@
);
},
+ /**
+ * Saves the meta box reordering setting to the server.
+ *
+ * @since 7.1.0
+ *
+ * @memberof postboxes
+ *
+ * @param {boolean} enabled Whether meta box reordering is enabled.
+ * @return {void}
+ */
+ save_meta_box_reordering_state : function( enabled ) {
+ $.post(
+ ajaxurl,
+ {
+ action: 'meta-box-reordering',
+ enabled: enabled ? 1 : 0,
+ screenoptionnonce: $( '#screenoptionnonce' ).val()
+ },
+ function() {
+ wp.a11y.speak( __( 'Screen Options updated.' ) );
+ }
+ );
+ },
+
/**
* Saves the order of the postboxes to the server.
*
diff --git a/src/wp-admin/admin-ajax.php b/src/wp-admin/admin-ajax.php
index 3ad60f95766e3..5e3d484fae988 100644
--- a/src/wp-admin/admin-ajax.php
+++ b/src/wp-admin/admin-ajax.php
@@ -79,6 +79,7 @@
'add-user',
'closed-postboxes',
'hidden-columns',
+ 'meta-box-reordering',
'update-welcome-panel',
'menu-get-metabox',
'wp-link-ajax',
diff --git a/src/wp-admin/admin-header.php b/src/wp-admin/admin-header.php
index 92fbd3a4a2f79..263c76015524d 100644
--- a/src/wp-admin/admin-header.php
+++ b/src/wp-admin/admin-header.php
@@ -214,6 +214,8 @@
$admin_body_class .= ' block-editor-page wp-embed-responsive';
}
+$admin_body_class .= wp_is_meta_box_reordering_enabled() ? ' meta-box-reordering-enabled' : ' meta-box-reordering-disabled';
+
$admin_body_class .= ' wp-theme-' . sanitize_html_class( get_template() );
if ( is_child_theme() ) {
$admin_body_class .= ' wp-child-theme-' . sanitize_html_class( get_stylesheet() );
diff --git a/src/wp-admin/css/common.css b/src/wp-admin/css/common.css
index 784166086af4f..4c588ce4d2166 100644
--- a/src/wp-admin/css/common.css
+++ b/src/wp-admin/css/common.css
@@ -1962,6 +1962,18 @@ p.auto-update-status {
line-height: 2.35;
}
+.metabox-prefs > p {
+ margin: 0 0 8px;
+}
+
+.additional-settings-prefs {
+ margin-top: 14px;
+}
+
+.additional-settings-prefs legend {
+ padding-bottom: 2px;
+}
+
#number-of-columns {
display: inline-block;
vertical-align: middle;
@@ -2259,6 +2271,11 @@ html.wp-toolbar {
width: 1.62rem;
}
+.js.meta-box-reordering-disabled .postbox .handle-order-higher,
+.js.meta-box-reordering-disabled .postbox .handle-order-lower {
+ display: none;
+}
+
/* Post box order buttons in the block editor meta boxes area. */
.edit-post-meta-boxes-area .postbox .handle-order-higher,
.edit-post-meta-boxes-area .postbox .handle-order-lower {
diff --git a/src/wp-admin/css/dashboard.css b/src/wp-admin/css/dashboard.css
index 1f1207606439e..2a4b0bcb09931 100644
--- a/src/wp-admin/css/dashboard.css
+++ b/src/wp-admin/css/dashboard.css
@@ -1408,6 +1408,10 @@ a.rsswidget {
}
}
+.js.meta-box-reordering-disabled #dashboard-widgets .postbox-container .empty-container {
+ display: none;
+}
+
@media screen and (max-width: 870px) {
/* @deprecated 5.9.0 -- Lists removed from welcome panel. */
.welcome-panel .welcome-panel-column li {
diff --git a/src/wp-admin/includes/ajax-actions.php b/src/wp-admin/includes/ajax-actions.php
index a04de73bd64e4..276c8fa879e79 100644
--- a/src/wp-admin/includes/ajax-actions.php
+++ b/src/wp-admin/includes/ajax-actions.php
@@ -1856,6 +1856,25 @@ function wp_ajax_hidden_columns() {
wp_die( 1 );
}
+/**
+ * Handles the meta box reordering setting via Ajax.
+ *
+ * @since 7.1.0
+ */
+function wp_ajax_meta_box_reordering() {
+ check_ajax_referer( 'screen-options-nonce', 'screenoptionnonce' );
+
+ $user = wp_get_current_user();
+ if ( ! $user ) {
+ wp_die( -1 );
+ }
+
+ $enabled = isset( $_POST['enabled'] ) && '1' === (string) $_POST['enabled'];
+ update_user_meta( $user->ID, 'meta_box_reordering', $enabled ? 'enabled' : 'disabled' );
+
+ wp_die( 1 );
+}
+
/**
* Handles updating whether to display the welcome panel via AJAX.
*
diff --git a/src/wp-admin/includes/class-wp-screen.php b/src/wp-admin/includes/class-wp-screen.php
index ab7dfef77f67c..ac2297e63d40c 100644
--- a/src/wp-admin/includes/class-wp-screen.php
+++ b/src/wp-admin/includes/class-wp-screen.php
@@ -1006,11 +1006,23 @@ public function show_screen_options() {
$this->_screen_settings = '';
+ $additional_settings = '';
+
+ if ( $this->show_meta_box_reordering_options() ) {
+ $additional_settings .= $this->get_meta_box_reordering_option();
+ }
+
if ( 'post' === $this->base ) {
- $expand = '
';
- $this->_screen_settings = $expand;
+ $additional_settings .= '';
+ }
+
+ if ( $additional_settings ) {
+ $this->_screen_settings = '';
}
/**
@@ -1023,7 +1035,7 @@ public function show_screen_options() {
*/
$this->_screen_settings = apply_filters( 'screen_settings', $this->_screen_settings, $this );
- if ( $this->_screen_settings || $this->_options ) {
+ if ( $this->_screen_settings || $this->_options || $this->show_meta_box_reordering_options() ) {
$show_screen = true;
}
@@ -1120,8 +1132,8 @@ public function render_meta_boxes_preferences() {