From 96e603b9a9c1a3c4c8d2a59a6212d8ea7e434cd8 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Tue, 14 Jul 2026 15:50:12 -0500 Subject: [PATCH 01/34] Add support for tooltips for metabox controls This PR wraps the existing buttons in markup for existing styles and scripts, but doesn't change the function signature to support adding all of the custom markup. It may be desirable to add a modified path to inject this markup into existing patterns. This could be done similar to `wp_get_admin_notice()`, which has a bunch of parsers for attributes, but I think this isn't appropriate here. Open to ideas, but I was thinking of something that accepted existing button markup, used the HTML API to inject the additional button markup, then accepted a string for tooltip text. I don't think this is needed for toggletips, but for existing markup needing tooltips, it may be helpful. See https://core.trac.wordpress.org/ticket/50921 --- src/wp-admin/css/wp-tooltip.css | 1 - src/wp-admin/includes/template.php | 34 +++++++++++++++++++++--------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/wp-admin/css/wp-tooltip.css b/src/wp-admin/css/wp-tooltip.css index 04ac5cd131ea9..c7c937d7b45e1 100644 --- a/src/wp-admin/css/wp-tooltip.css +++ b/src/wp-admin/css/wp-tooltip.css @@ -3,7 +3,6 @@ .wp-tooltip { display: inline-flex; align-items: center; - vertical-align: middle; } /* Toggle and close buttons. */ diff --git a/src/wp-admin/includes/template.php b/src/wp-admin/includes/template.php index 70b8249ed9c55..d8d017e50154a 100644 --- a/src/wp-admin/includes/template.php +++ b/src/wp-admin/includes/template.php @@ -1338,6 +1338,8 @@ function do_meta_boxes( $screen, $context, $data_object ) { $i = 0; if ( isset( $wp_meta_boxes[ $page ][ $context ] ) ) { + wp_enqueue_script( 'wp-tooltip' ); + wp_enqueue_style( 'wp-tooltip' ); foreach ( array( 'high', 'sorted', 'core', 'default', 'low' ) as $priority ) { if ( isset( $wp_meta_boxes[ $page ][ $context ][ $priority ] ) ) { foreach ( (array) $wp_meta_boxes[ $page ][ $context ][ $priority ] as $box ) { @@ -1396,41 +1398,53 @@ function do_meta_boxes( $screen, $context, $data_object ) { } echo '
'; - - echo ''; - echo ''; + echo '
'; - echo ''; - echo ''; + echo ''; - echo ''; + echo ''; + echo '' . $show_hide_text . ''; + echo ''; + echo ''; echo ''; } From d877331cc9ca62156ee784d18710b203fcd3ff44 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Tue, 14 Jul 2026 15:53:08 -0500 Subject: [PATCH 02/34] Update template.php --- src/wp-admin/includes/template.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-admin/includes/template.php b/src/wp-admin/includes/template.php index d8d017e50154a..304285056cef2 100644 --- a/src/wp-admin/includes/template.php +++ b/src/wp-admin/includes/template.php @@ -1398,7 +1398,7 @@ function do_meta_boxes( $screen, $context, $data_object ) { } echo '
'; - + echo '
'; echo ''; echo ' - ' . sprintf( - /* translators: %s: Meta box title. */ - __( 'Move %s box up' ), - $widget_title - ) . ''; + ' . $move_up_text . ''; echo '
'; + $move_down_text = sprintf( + /* translators: %s: Meta box title. */ + __( 'Move %s box down' ), + $widget_title + ); echo '
'; echo ''; echo ' - ' . sprintf( - /* translators: %s: Meta box title. */ - __( 'Move %s box down' ), - $widget_title - ) . ''; + ' . $move_down_text . ''; echo '
'; $show_hide_text = sprintf( From 679511c19da1dee572f6a6a8048a4c547bce2591 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Wed, 15 Jul 2026 16:34:04 -0500 Subject: [PATCH 04/34] Add HTML API parsing of button markup. Uses the HTML API to process passed markup and insert into required pattern. Allows passing existing buttons without needing to add support for custom attributes. Adds tests to verify markup changes. --- src/wp-admin/includes/template.php | 58 ++++++++++---------- src/wp-includes/general-template.php | 35 ++++++++---- tests/phpunit/tests/general/wpGetTooltip.php | 18 ++++++ 3 files changed, 73 insertions(+), 38 deletions(-) diff --git a/src/wp-admin/includes/template.php b/src/wp-admin/includes/template.php index afc0c3b8858f2..8e3f52259b367 100644 --- a/src/wp-admin/includes/template.php +++ b/src/wp-admin/includes/template.php @@ -1399,48 +1399,50 @@ function do_meta_boxes( $screen, $context, $data_object ) { echo '
'; - $move_up_text = sprintf( + $move_up_text = sprintf( /* translators: %s: Meta box title. */ __( 'Move %s box up' ), $widget_title ); - echo '
'; - echo ''; - echo ' - ' . $move_up_text . ''; - echo '
'; + $move_up_button = ''; + $move_up_args = array( + 'id' => $box['id'] . '-handle-order-higher-description', + 'button' => $move_up_button, + ); + echo wp_get_tooltip( $move_up_text, $move_up_args ); - $move_down_text = sprintf( + $move_down_text = sprintf( /* translators: %s: Meta box title. */ __( 'Move %s box down' ), $widget_title ); - echo '
'; - echo ''; - echo ' - ' . $move_down_text . ''; - echo '
'; + $move_down_button = ''; + $move_down_args = array( + 'id' => $box['id'] . '-handle-order-lower-description', + 'button' => $move_down_button, + ); + echo wp_get_tooltip( $move_down_text, $move_down_args ); - $show_hide_text = sprintf( + $show_hide_text = sprintf( /* translators: %s: Hidden accessibility text. Meta box title. */ __( 'Show or hide panel: %s' ), $widget_title ); - echo '
'; - echo ''; - echo ''; - echo '' . $show_hide_text . ''; - echo ''; - echo '
'; + $show_hide_button = ''; + $show_hide_args = array( + 'id' => $box['id'] . '-handlediv', + 'button' => $show_hide_button, + ); + echo wp_get_tooltip( $show_hide_text, $show_hide_args ); echo '
'; } diff --git a/src/wp-includes/general-template.php b/src/wp-includes/general-template.php index 36f3db3beba10..5476d9e41efa9 100644 --- a/src/wp-includes/general-template.php +++ b/src/wp-includes/general-template.php @@ -446,6 +446,8 @@ function wp_get_toggletip( $content, $args ) { * * @type string $id Unique ID for the popover element. Default is a * generated unique ID. + * @type string $button Existing `button` markup. Used instead of generated button. + * Default empty. * @type string $label Accessible label for the toggle button. * Default 'Help', matching the default icon. * Ignored for tooltips. @@ -469,6 +471,7 @@ function wp_get_tooltip_helper( $content, $args = array() ) { $defaults = array( 'id' => '', + 'button' => '', 'label' => __( 'Help' ), 'close_label' => __( 'Close' ), 'icon' => 'dashicons-editor-help', @@ -488,15 +491,29 @@ function wp_get_tooltip_helper( $content, $args = array() ) { $icon = '' !== $args['icon'] ? ' ' . $args['icon'] : ''; + $button = ''; + if ( ! empty( $args['button'] ) ) { + $processor = new WP_HTML_Tag_Processor( $args['button'] ); + if ( $processor->next_tag( 'button' ) ) { + $processor->set_attribute( 'popovertarget', '%2$s' ); + $processor->add_class( 'wp-tooltip__toggle' ); + if ( 'tooltip' !== $args['type'] ) { + $processor->set_attribute( 'aria-haspopup', 'dialog' ); + } + + $button = $processor->get_updated_html(); + } + } + if ( 'tooltip' === $args['type'] ) { // Tooltips are only used to visually display labels. $label = wp_strip_all_tags( $content, true ); $markup = sprintf( - '
' . - '' . - '' . + '
+ ' . $button . ' + ' . '%5$s' . '' . '
', @@ -508,11 +525,9 @@ function wp_get_tooltip_helper( $content, $args = array() ) { ); } else { $markup = sprintf( - '
' . - '' . - '' . + '
+ ' . $button . ' + ' . '%5$s' . '', + ) + ); + + $this->assertStringContainsString( 'aria-expanded="false"', $html, 'String contains attribute not supported in function.' ); + $this->assertStringContainsString( 'popovertarget', $html, 'String contains required attribute added by function.' ); + $this->assertStringNotContainsString( 'dashicons', $html, 'String does not contain content of default button.' ); + } + /** * Tests that the accessible labels are output and escaped in attributes. * From 69bf5ff8a918436cc5d37ad3a6ad0ad3d123ecbd Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Wed, 15 Jul 2026 16:47:12 -0500 Subject: [PATCH 05/34] Add styles to reduce highlighting of tooltips when on disabled buttons Provides a similar queue as the grayed out button. Non-sighted users will be notified that this button is disabled, sighted users have to get that from context: grayed out design & inference from the position of the box. I think that should be sufficient. --- src/wp-admin/css/wp-tooltip.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/wp-admin/css/wp-tooltip.css b/src/wp-admin/css/wp-tooltip.css index c7c937d7b45e1..0da2fc1003076 100644 --- a/src/wp-admin/css/wp-tooltip.css +++ b/src/wp-admin/css/wp-tooltip.css @@ -71,6 +71,11 @@ line-height: 1.4; } +.wp-tooltip:has(button[aria-disabled="true"],button[disabled="true"]) .wp-tooltip__bubble { + background: #50575e; + color: #c3c4c7; +} + .wp-tooltip:not(.wp-is-tooltip) .wp-tooltip__text { display: block; padding-inline-end: 24px; From 87bbb5d953658535e5bb96eb705f8ed9b3cdbb28 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Wed, 15 Jul 2026 17:00:44 -0500 Subject: [PATCH 06/34] Need to process all buttons --- src/wp-includes/general-template.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/wp-includes/general-template.php b/src/wp-includes/general-template.php index 5476d9e41efa9..54fc7a09163d8 100644 --- a/src/wp-includes/general-template.php +++ b/src/wp-includes/general-template.php @@ -494,17 +494,17 @@ function wp_get_tooltip_helper( $content, $args = array() ) { $button = ''; - if ( ! empty( $args['button'] ) ) { - $processor = new WP_HTML_Tag_Processor( $args['button'] ); - if ( $processor->next_tag( 'button' ) ) { - $processor->set_attribute( 'popovertarget', '%2$s' ); - $processor->add_class( 'wp-tooltip__toggle' ); - if ( 'tooltip' !== $args['type'] ) { - $processor->set_attribute( 'aria-haspopup', 'dialog' ); - } - $button = $processor->get_updated_html(); + $button = ( ! empty( $args['button'] ) ) ? $args['button'] : $button; + $processor = new WP_HTML_Tag_Processor( $button ); + if ( $processor->next_tag( 'button' ) ) { + $processor->set_attribute( 'popovertarget', '%2$s' ); + $processor->add_class( 'wp-tooltip__toggle' ); + if ( 'tooltip' !== $args['type'] ) { + $processor->set_attribute( 'aria-haspopup', 'dialog' ); } + + $button = $processor->get_updated_html(); } if ( 'tooltip' === $args['type'] ) { From 1332e477b2062f29a8d0000b334d04ee0b41bc78 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Wed, 15 Jul 2026 17:13:22 -0500 Subject: [PATCH 07/34] Using the HTML API changes the order of button attributes --- tests/phpunit/tests/general/wpGetTooltip.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/general/wpGetTooltip.php b/tests/phpunit/tests/general/wpGetTooltip.php index e2ad6cbe45e1c..87402476044e0 100644 --- a/tests/phpunit/tests/general/wpGetTooltip.php +++ b/tests/phpunit/tests/general/wpGetTooltip.php @@ -29,7 +29,7 @@ public function test_wp_get_tooltip_returns_accessible_markup() { $tooltip = wp_get_tooltip( 'Helpful text.', array( 'id' => 'my-tip' ) ); // Toggle is a button that controls the popover and describes it. - $this->assertStringContainsString( ''; + + $button = ( ! empty( $args['button'] ) ) ? $args['button'] : $button; + $processor = new WP_HTML_Tag_Processor( $button ); + if ( $processor->next_tag( 'button' ) ) { + $processor->set_attribute( 'popovertarget', '%2$s' ); + $processor->add_class( 'wp-tooltip__toggle' ); + if ( 'tooltip' !== $args['type'] ) { + $processor->set_attribute( 'aria-haspopup', 'dialog' ); + } + $button = $processor->get_updated_html(); + } /* * The markup only uses phrasing content so it is valid when nested * in a phrasing context. Sectioning content (e.g. `div`, `dialog`) will @@ -501,11 +514,9 @@ function wp_get_tooltip_helper( $content, $args = array() ) { // Tooltips are only used to visually display labels. $label = wp_strip_all_tags( $content, true ); $markup = sprintf( - '' . - '' . - '' . + ' + ' . $button . ' + ' . '%5$s' . '' . '', @@ -522,11 +533,9 @@ function wp_get_tooltip_helper( $content, $args = array() ) { * attributes reproduce the accessible name and focus handling of the native element. */ $markup = sprintf( - '' . - '' . - '' . + ' + ' . $button . ' + ' . '%5$s' . ''; $move_up_args = array( 'id' => $box['id'] . '-handle-order-higher-description', 'button' => $move_up_button, ); - echo wp_get_tooltip( $move_up_text, $move_up_args ); + echo wp_get_tooltip( __( 'Move up' ), $move_up_args ); - $move_down_text = sprintf( - /* translators: %s: Meta box title. */ - __( 'Move %s box down' ), - $widget_title - ); $move_down_button = ''; $move_down_args = array( 'id' => $box['id'] . '-handle-order-lower-description', 'button' => $move_down_button, ); - echo wp_get_tooltip( $move_down_text, $move_down_args ); + echo wp_get_tooltip( __( 'Move down' ), $move_down_args ); - $show_hide_text = sprintf( - /* translators: %s: Hidden accessibility text. Meta box title. */ - __( 'Show or hide panel: %s' ), - $widget_title - ); $show_hide_button = ''; $show_hide_args = array( 'id' => $box['id'] . '-handlediv', 'button' => $show_hide_button, ); - echo wp_get_tooltip( $show_hide_text, $show_hide_args ); + echo wp_get_tooltip( __( 'Show or hide panel' ), $show_hide_args ); echo '
'; } From 4b5bb1295d5ac3e4a6aef40bd1762ad993a2ae1c Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Sun, 19 Jul 2026 19:24:42 -0500 Subject: [PATCH 11/34] Move default values to default args array --- src/wp-includes/general-template.php | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/wp-includes/general-template.php b/src/wp-includes/general-template.php index 4cab85cae8d46..a1efc48f1d2c4 100644 --- a/src/wp-includes/general-template.php +++ b/src/wp-includes/general-template.php @@ -471,8 +471,8 @@ function wp_get_tooltip_helper( $content, $args = array() ) { } $defaults = array( - 'id' => '', - 'button' => '', + 'id' => wp_unique_id( 'wp-tooltip-' ), + 'button' => '', 'label' => __( 'Help' ), 'close_label' => __( 'Close' ), 'icon' => 'dashicons-editor-help', @@ -482,18 +482,12 @@ function wp_get_tooltip_helper( $content, $args = array() ) { $args = wp_parse_args( $args, $defaults ); - $id = '' !== $args['id'] ? $args['id'] : wp_unique_id( 'wp-tooltip-' ); - $classes = ( 'tooltip' === $args['type'] ) ? 'wp-tooltip wp-is-tooltip' : 'wp-tooltip wp-is-toggletip'; if ( '' !== $args['class'] ) { $classes .= ' ' . $args['class']; } - $icon = '' !== $args['icon'] ? ' ' . $args['icon'] : ''; - $button = ''; - + $icon = '' !== $args['icon'] ? ' ' . $args['icon'] : ''; $button = ( ! empty( $args['button'] ) ) ? $args['button'] : $button; $processor = new WP_HTML_Tag_Processor( $button ); if ( $processor->next_tag( 'button' ) ) { From a31c87cca68b881c3c8e3964efd9e4609cf2d483 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Sun, 19 Jul 2026 19:27:33 -0500 Subject: [PATCH 12/34] $id now undefined --- src/wp-includes/general-template.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/general-template.php b/src/wp-includes/general-template.php index a1efc48f1d2c4..697f531c00072 100644 --- a/src/wp-includes/general-template.php +++ b/src/wp-includes/general-template.php @@ -515,7 +515,7 @@ function wp_get_tooltip_helper( $content, $args = array() ) { '' . '', esc_attr( $classes ), - esc_attr( $id ), + esc_attr( $args['id'] ), esc_attr( $label ), esc_attr( $icon ), esc_html( $content ), @@ -537,7 +537,7 @@ function wp_get_tooltip_helper( $content, $args = array() ) { '' . '', esc_attr( $classes ), - esc_attr( $id ), + esc_attr( $args['id'] ), esc_attr( $args['label'] ), esc_attr( $icon ), esc_html( $content ), From 11955b5247259820b6a1aab3f6545b3a76cd3dc8 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Sun, 19 Jul 2026 19:28:06 -0500 Subject: [PATCH 13/34] Don't override hover/focus when disabled. Toggle tip case not covered, as a toggle tip should never be disabled. --- src/wp-admin/css/wp-tooltip.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wp-admin/css/wp-tooltip.css b/src/wp-admin/css/wp-tooltip.css index c7c937d7b45e1..cf728860240b2 100644 --- a/src/wp-admin/css/wp-tooltip.css +++ b/src/wp-admin/css/wp-tooltip.css @@ -21,14 +21,14 @@ cursor: pointer; } -.wp-tooltip .wp-tooltip__toggle:hover, -.wp-tooltip .wp-tooltip__toggle:focus, +.wp-tooltip:not(:has(button[aria-disabled="true"],button[disabled="true"])) .wp-tooltip__toggle:hover, +.wp-tooltip:not(:has(button[aria-disabled="true"],button[disabled="true"])) .wp-tooltip__toggle:focus, .wp-tooltip .wp-tooltip__close:hover, .wp-tooltip .wp-tooltip__close:focus { color: var(--wp-admin-theme-color, #3858e9); } -.wp-tooltip .wp-tooltip__toggle:focus, +.wp-tooltip:not(:has(button[aria-disabled="true"],button[disabled="true"])) .wp-tooltip__toggle:focus, .wp-tooltip .wp-tooltip__close:focus { outline: 2px solid transparent; box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) var(--wp-admin-theme-color, #3858e9); From 7fd7bdbc2120db0458947f4f463fd770f0ea83cd Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Sun, 19 Jul 2026 19:28:55 -0500 Subject: [PATCH 14/34] Update template.php --- src/wp-admin/includes/template.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-admin/includes/template.php b/src/wp-admin/includes/template.php index 186e77a6be9ac..4e162e7c54acc 100644 --- a/src/wp-admin/includes/template.php +++ b/src/wp-admin/includes/template.php @@ -1374,7 +1374,7 @@ function do_meta_boxes( $screen, $context, $data_object ) { ++$i; // get_hidden_meta_boxes() doesn't apply in the block editor. $hidden_class = ( ! $screen->is_block_editor() && in_array( $box['id'], $hidden, true ) ) ? ' hide-if-js' : ''; - echo '
' . "\n"; + echo '
' . "\n"; echo '
'; echo '

'; From 1cce6b192b5339978efd6c857c288b134dbb1c28 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Mon, 20 Jul 2026 10:47:44 -0500 Subject: [PATCH 15/34] Add aria-describedby referencing widget container ID. --- src/wp-admin/includes/template.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wp-admin/includes/template.php b/src/wp-admin/includes/template.php index 4e162e7c54acc..42481ed2c2c10 100644 --- a/src/wp-admin/includes/template.php +++ b/src/wp-admin/includes/template.php @@ -1399,7 +1399,7 @@ function do_meta_boxes( $screen, $context, $data_object ) { echo '
'; - $move_up_button = ''; @@ -1409,7 +1409,7 @@ function do_meta_boxes( $screen, $context, $data_object ) { ); echo wp_get_tooltip( __( 'Move up' ), $move_up_args ); - $move_down_button = ''; @@ -1419,7 +1419,7 @@ function do_meta_boxes( $screen, $context, $data_object ) { ); echo wp_get_tooltip( __( 'Move down' ), $move_down_args ); - $show_hide_button = ''; From 4bac23fed21136dff662cb525b2b112247d0cb98 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Mon, 20 Jul 2026 16:50:50 -0500 Subject: [PATCH 16/34] Remove popovertarget on tooltips Prevents double reading for VoiceOver --- src/wp-includes/general-template.php | 2 +- tests/phpunit/tests/general/wpGetTooltip.php | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/general-template.php b/src/wp-includes/general-template.php index 697f531c00072..40af1f115b5f2 100644 --- a/src/wp-includes/general-template.php +++ b/src/wp-includes/general-template.php @@ -491,9 +491,9 @@ function wp_get_tooltip_helper( $content, $args = array() ) { $button = ( ! empty( $args['button'] ) ) ? $args['button'] : $button; $processor = new WP_HTML_Tag_Processor( $button ); if ( $processor->next_tag( 'button' ) ) { - $processor->set_attribute( 'popovertarget', '%2$s' ); $processor->add_class( 'wp-tooltip__toggle' ); if ( 'tooltip' !== $args['type'] ) { + $processor->set_attribute( 'popovertarget', '%2$s' ); $processor->set_attribute( 'aria-haspopup', 'dialog' ); } $button = $processor->get_updated_html(); diff --git a/tests/phpunit/tests/general/wpGetTooltip.php b/tests/phpunit/tests/general/wpGetTooltip.php index c1bceee4596d5..6f5698654195a 100644 --- a/tests/phpunit/tests/general/wpGetTooltip.php +++ b/tests/phpunit/tests/general/wpGetTooltip.php @@ -28,9 +28,9 @@ public function test_wp_get_tooltip_returns_empty_string_without_content() { public function test_wp_get_tooltip_returns_accessible_markup() { $tooltip = wp_get_tooltip( 'Helpful text.', array( 'id' => 'my-tip' ) ); - // Toggle is a button that controls the popover and describes it. - $this->assertStringContainsString( '', + 'button' => '', 'label' => __( 'Help' ), 'close_label' => __( 'Close' ), 'icon' => 'dashicons-editor-help', @@ -487,7 +487,7 @@ function wp_get_tooltip_helper( $content, $args = array() ) { $classes .= ' ' . $args['class']; } - $icon = ( $args['icon'] ) ? ' ' . trim( $args['icon'] ) : $defaults['icon']; + $icon = ( $args['icon'] ) ? trim( $args['icon'] ) : $defaults['icon']; $id = ( $args['id'] ) ? $args['id'] : $defaults['id']; $button = ( $args['button'] ) ? $args['button'] : $defaults['button']; $processed = false; From 0ab435ac5f46543b163fae0450e49b43b323886d Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Tue, 21 Jul 2026 15:42:41 -0500 Subject: [PATCH 30/34] Move wp-tooltip.css to a global admin style; move wp-tooltip to a postbox dependency. It's possible that both scripts should be enqueued globally; with this, extenders would need to require `wp-tooltip`, but would not need to require the CSS in the admin. --- src/wp-admin/includes/template.php | 2 -- src/wp-includes/script-loader.php | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/wp-admin/includes/template.php b/src/wp-admin/includes/template.php index 25e68b4a961d6..fa803e86e0fb0 100644 --- a/src/wp-admin/includes/template.php +++ b/src/wp-admin/includes/template.php @@ -1338,8 +1338,6 @@ function do_meta_boxes( $screen, $context, $data_object ) { $i = 0; if ( isset( $wp_meta_boxes[ $page ][ $context ] ) ) { - wp_enqueue_script( 'wp-tooltip' ); - wp_enqueue_style( 'wp-tooltip' ); foreach ( array( 'high', 'sorted', 'core', 'default', 'low' ) as $priority ) { if ( isset( $wp_meta_boxes[ $page ][ $context ][ $priority ] ) ) { foreach ( (array) $wp_meta_boxes[ $page ][ $context ][ $priority ] as $box ) { diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php index d777ecccc4373..fd1f24a08968d 100644 --- a/src/wp-includes/script-loader.php +++ b/src/wp-includes/script-loader.php @@ -1439,7 +1439,7 @@ function wp_default_scripts( $scripts ) { $scripts->add( 'xfn', "/wp-admin/js/xfn$suffix.js", array( 'jquery' ), false, 1 ); - $scripts->add( 'postbox', "/wp-admin/js/postbox$suffix.js", array( 'jquery-ui-sortable', 'wp-a11y' ), false, 1 ); + $scripts->add( 'postbox', "/wp-admin/js/postbox$suffix.js", array( 'jquery-ui-sortable', 'wp-a11y', 'wp-tooltip' ), false, 1 ); $scripts->set_translations( 'postbox' ); $scripts->add( 'tags-box', "/wp-admin/js/tags-box$suffix.js", array( 'jquery', 'tags-suggest' ), false, 1 ); @@ -1638,7 +1638,7 @@ function wp_default_styles( $styles ) { $styles->add( 'code-editor', "/wp-admin/css/code-editor$suffix.css", array( 'wp-codemirror' ) ); $styles->add( 'site-health', "/wp-admin/css/site-health$suffix.css" ); - $styles->add( 'wp-admin', false, array( 'dashicons', 'common', 'forms', 'admin-menu', 'dashboard', 'list-tables', 'edit', 'revisions', 'media', 'themes', 'about', 'nav-menus', 'widgets', 'site-icon', 'l10n', 'wp-base-styles' ) ); + $styles->add( 'wp-admin', false, array( 'dashicons', 'common', 'forms', 'admin-menu', 'dashboard', 'list-tables', 'edit', 'revisions', 'media', 'themes', 'about', 'nav-menus', 'widgets', 'site-icon', 'l10n', 'wp-base-styles', 'wp-tooltip' ) ); $styles->add( 'login', "/wp-admin/css/login$suffix.css", array( 'dashicons', 'buttons', 'forms', 'l10n', 'wp-base-styles', 'wp-tooltip' ) ); $styles->add( 'install', "/wp-admin/css/install$suffix.css", array( 'dashicons', 'buttons', 'forms', 'l10n', 'wp-base-styles' ) ); From 942e7e438743bc234b57e936ccb1162f1abdcc54 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Tue, 21 Jul 2026 18:22:06 -0500 Subject: [PATCH 31/34] Improve docs for wp_get_toggletip() and pass default arg This matches the Optional declaration in function docs to the actual function signature. Props @jeremyfelt --- src/wp-includes/general-template.php | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/wp-includes/general-template.php b/src/wp-includes/general-template.php index 2faa5116a5587..b539f9d0be33f 100644 --- a/src/wp-includes/general-template.php +++ b/src/wp-includes/general-template.php @@ -373,7 +373,7 @@ function get_search_form( $args = array() ) { /** * Retrieves the markup for an accessible tooltip. * - * Returns a button with an accessible name popover. + * Returns a button with an accessible name popover hint. * * @since 7.1.0 * @@ -399,12 +399,9 @@ function wp_get_tooltip( $content, $args = array() ) { } /** - * Retrieves the markup for an accessible tooltip or toggletip. + * Retrieves the markup for an accessible toggle tip. * - * Returns a button and either a hover/focus triggered tooltip popover or an action - * triggered toggle tip. Enqueue the `wp-tooltip` style and script where it is used. - * Tooltips are used to show the accessible name of a control. - * Toggletips are be used for longer supporting text explaining context. + * Returns a button and an action triggered toggle tip with `$content`. * * @since 7.1.0 * @@ -424,9 +421,9 @@ function wp_get_tooltip( $content, $args = array() ) { * @type string $class Additional class(es) for the wrapping element. * Default empty. * } - * @return string Tooltip HTML markup, or an empty string when no content is provided. + * @return string Toggletip HTML markup, or an empty string when no content is provided. */ -function wp_get_toggletip( $content, $args ) { +function wp_get_toggletip( $content, $args = array() ) { $args['type'] = 'toggletip'; return wp_get_tooltip_helper( $content, $args ); } From 779549b8d11b19e01045ba6a4bf30e9d44fb383f Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Tue, 21 Jul 2026 18:25:28 -0500 Subject: [PATCH 32/34] Set aria-describedby to h2 heading, instead of container. --- src/wp-admin/includes/template.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wp-admin/includes/template.php b/src/wp-admin/includes/template.php index fa803e86e0fb0..bafd5f0904769 100644 --- a/src/wp-admin/includes/template.php +++ b/src/wp-admin/includes/template.php @@ -1375,7 +1375,7 @@ function do_meta_boxes( $screen, $context, $data_object ) { echo '
' . "\n"; echo '
'; - echo '

'; + echo '

'; if ( 'dashboard_php_nag' === $box['id'] ) { echo ''; echo '' . @@ -1397,7 +1397,7 @@ function do_meta_boxes( $screen, $context, $data_object ) { echo '
'; - $move_up_button = ''; @@ -1407,7 +1407,7 @@ function do_meta_boxes( $screen, $context, $data_object ) { ); echo wp_get_tooltip( __( 'Move up' ), $move_up_args ); - $move_down_button = ''; @@ -1417,7 +1417,7 @@ function do_meta_boxes( $screen, $context, $data_object ) { ); echo wp_get_tooltip( __( 'Move down' ), $move_down_args ); - $show_hide_button = ''; From 96a9289af437e6231125675932413422c56ed2c7 Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Tue, 21 Jul 2026 18:33:08 -0500 Subject: [PATCH 33/34] Bah. --- src/wp-includes/general-template.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/general-template.php b/src/wp-includes/general-template.php index b539f9d0be33f..d6b51a7041ef0 100644 --- a/src/wp-includes/general-template.php +++ b/src/wp-includes/general-template.php @@ -401,7 +401,7 @@ function wp_get_tooltip( $content, $args = array() ) { /** * Retrieves the markup for an accessible toggle tip. * - * Returns a button and an action triggered toggle tip with `$content`. + * Returns a button and an action triggered toggle tip with `$content`. * * @since 7.1.0 * From 556c3dc1211000b6b3f65d0e9f602a469c990f6c Mon Sep 17 00:00:00 2001 From: Joe Dolson Date: Tue, 21 Jul 2026 18:57:20 -0500 Subject: [PATCH 34/34] Reflect `$button` argument in docsl --- src/wp-includes/general-template.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wp-includes/general-template.php b/src/wp-includes/general-template.php index d6b51a7041ef0..29c30137e173d 100644 --- a/src/wp-includes/general-template.php +++ b/src/wp-includes/general-template.php @@ -383,6 +383,8 @@ function get_search_form( $args = array() ) { * * @type string $id Unique ID for the popover element. Default is a * generated unique ID. + * @type string $button Existing `button` or `a` markup. Used instead of generated button. + * Default standard button HTML. * @type string $label Not used for tooltips. * @type string $close_label Not used for tooltips. * @type string $icon Dashicons icon class for the toggle button. @@ -411,6 +413,8 @@ function wp_get_tooltip( $content, $args = array() ) { * * @type string $id Unique ID for the popover element. Default is a * generated unique ID. + * @type string $button Existing `button` markup. Used instead of generated button. + * Default standard button HTML. * @type string $label Accessible label for the toggle button. * Default 'Help', matching the default icon. * Ignored for tooltips.