diff --git a/src/js/_enqueues/wp/wp-tooltip.js b/src/js/_enqueues/wp/wp-tooltip.js index 5d9621c0a4e83..70fe2bfe7c1b2 100644 --- a/src/js/_enqueues/wp/wp-tooltip.js +++ b/src/js/_enqueues/wp/wp-tooltip.js @@ -14,8 +14,9 @@ let openTimeout; popovers.forEach( function( popover ) { - const trigger = /** @type {HTMLButtonElement|null} */ ( popover.querySelector( 'button.wp-tooltip__toggle' ) ); + const trigger = /** @type {HTMLButtonElement|HTMLAnchorElement|null} */ ( popover.querySelector( '.wp-tooltip__toggle' ) ); const panel = /** @type {HTMLSpanElement|null} */ ( popover.querySelector( 'span.wp-tooltip__bubble' ) ); + if ( ! trigger || ! panel ) { return; } diff --git a/src/wp-admin/css/wp-tooltip.css b/src/wp-admin/css/wp-tooltip.css index 04ac5cd131ea9..cf728860240b2 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. */ @@ -22,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); diff --git a/src/wp-admin/includes/class-wp-list-table.php b/src/wp-admin/includes/class-wp-list-table.php index d32f08a438c60..e784b35c267af 100644 --- a/src/wp-admin/includes/class-wp-list-table.php +++ b/src/wp-admin/includes/class-wp-list-table.php @@ -809,6 +809,9 @@ protected function view_switcher( $current_mode ) {
modes as $mode => $title ) { $classes = array( 'view-' . $mode ); $aria_current = ''; @@ -818,14 +821,18 @@ protected function view_switcher( $current_mode ) { $aria_current = ' aria-current="page"'; } - printf( - "" . - "%s" . - "\n", + $switcher_link = sprintf( + "\n", esc_url( remove_query_arg( 'attachment-filter', add_query_arg( 'mode', $mode ) ) ), - implode( ' ', $classes ), - $title + esc_attr( $title ), + implode( ' ', $classes ) + ); + + $switcher_link_args = array( + 'id' => "view-switch-$mode-tooltip", + 'button' => $switcher_link, ); + echo wp_get_tooltip( $title, $switcher_link_args ); } ?>
diff --git a/src/wp-admin/includes/template.php b/src/wp-admin/includes/template.php index 764e904005fd4..4e162e7c54acc 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 ) { @@ -1372,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 '

'; @@ -1397,40 +1399,35 @@ function do_meta_boxes( $screen, $context, $data_object ) { echo '
'; - echo ''; - echo ''; - - echo ''; - echo ''; - - 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' ), $move_up_args ); + + $move_down_button = ''; + $move_down_args = array( + 'id' => $box['id'] . '-handle-order-lower-description', + 'button' => $move_down_button, + ); + echo wp_get_tooltip( __( 'Move down' ), $move_down_args ); + + $show_hide_button = ''; + $show_hide_args = array( + 'id' => $box['id'] . '-handlediv', + 'button' => $show_hide_button, + ); + echo wp_get_tooltip( __( 'Show or hide panel' ), $show_hide_args ); echo '
'; } diff --git a/src/wp-includes/general-template.php b/src/wp-includes/general-template.php index ab3977a496e82..81daf126e1e9b 100644 --- a/src/wp-includes/general-template.php +++ b/src/wp-includes/general-template.php @@ -447,6 +447,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,7 +471,8 @@ function wp_get_tooltip_helper( $content, $args = array() ) { } $defaults = array( - 'id' => '', + 'id' => wp_unique_id( 'wp-tooltip-' ), + 'button' => '', 'label' => __( 'Help' ), 'close_label' => __( 'Close' ), 'icon' => 'dashicons-editor-help', @@ -479,14 +482,28 @@ 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'] : ''; + $icon = $args['icon']; + $button = $args['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 ( $processor->next_tag( 'a' ) && 'tooltip' === $args['type'] ) { + $processor->add_class( 'wp-tooltip__toggle' ); + $button = $processor->get_updated_html(); + } /* * The markup only uses phrasing content so it is valid when nested @@ -498,16 +515,14 @@ 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' . '' . '', esc_attr( $classes ), - esc_attr( $id ), + esc_attr( $args['id'] ), esc_attr( $label ), esc_attr( $icon ), esc_html( $content ), @@ -519,11 +534,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' . '', + ) + ); + + $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. *