Make WordPress Core

Changeset 61764

Timestamp:
02/27/2026 10:48:36 PM (5 days ago)
Author:
joedolson
Message:

Editor: A11y: Use a tablist pattern for taxonomy terms.

Switch the classic editor's taxonomy tabs to use the APG tablist/tabpanel structure. Add appropriate ARIA roles to tabs and panels and update JS to handle required keyboard events and selected states.

Props alh0319, mukesh27, joedolson.
Fixes #63981.

Location:
trunk/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/js/_enqueues/admin/link.js

    r50547 r61764  
    2020     * @return {boolean} Always returns false to prevent the default behavior.
    2121     */
    22     $('#category-tabs a').on( 'click', function(){
     22    $('#category-tabs a').on( 'click){
    2323        var t = $(this).attr('href');
    24         $(this).parent().addClass('tabs').siblings('li').removeClass('tabs');
    25         $('.tabs-panel').hide();
    26         $(t).show();
    27         if ( '#categories-all' == t )
    28             deleteUserSetting('cats');
    29         else
    30             setUserSetting('cats','pop');
    31         return false;
     24        if ( event.type === 'keydown' && event.key === ' ' ) {
     25            event.preventDefault();
     26        }
     27        if ( ( event.type === 'keyup' && event.key === ' ' ) || ( event.type === 'keydown' && event.key === 'Enter' ) || event.type === 'click' ) {
     28            event.preventDefault();
     29            $('#category-tabs a').removeAttr( 'aria-selected' ).attr( 'tabindex', '-1' );
     30            $(this).attr( 'aria-selected', 'true' ).removeAttr( 'tabindex' );
     31            $(this).parent().addClass('tabs').siblings('li').removeClass('tabs');
     32            $('.tabs-panel').hide();
     33            $(t).show();
     34            if ( '#categories-all' == t ) {
     35                deleteUserSetting('cats');
     36            } else {
     37                setUserSetting('cats','pop');
     38            }
     39            return false;
     40        }
     41        if ( event.type === 'keyup' && ( event.key === 'ArrowRight' || event.key === 'ArrowLeft' ) ) {
     42            $(this).attr( 'tabindex', '-1' );
     43            let next = $(this).parent('li').next();
     44            let prev = $(this).parent('li').prev();
     45            if ( next.length > 0 ) {
     46                next.find('a').removeAttr( 'tabindex');
     47                next.find('a').trigger( 'focus' );
     48            } else {
     49                prev.find('a').removeAttr( 'tabindex');
     50                prev.find('a').trigger( 'focus' );
     51            }
     52        }
    3253    });
    3354    if ( getUserSetting('cats') )
  • trunk/src/js/_enqueues/admin/post.js

    r59454 r61764  
    567567
    568568        // @todo Move to jQuery 1.3+, support for multiple hierarchical taxonomies, see wp-lists.js.
    569         $('a', '#' + taxonomy + '-tabs').on( 'click', function( e ) {
    570             e.preventDefault();
     569        $('a', '#' + taxonomy + '-tabs').on( 'click keyup keydown', function( event ) {
    571570            var t = $(this).attr('href');
    572             $(this).parent().addClass('tabs').siblings('li').removeClass('tabs');
    573             $('#' + taxonomy + '-tabs').siblings('.tabs-panel').hide();
    574             $(t).show();
    575             if ( '#' + taxonomy + '-all' == t ) {
    576                 deleteUserSetting( settingName );
    577             } else {
    578                 setUserSetting( settingName, 'pop' );
     571            if ( event.type === 'keydown' && event.key === ' ' ) {
     572                event.preventDefault();
     573            }
     574            if ( ( event.type === 'keyup' && event.key === ' ' ) || ( event.type === 'keydown' && event.key === 'Enter' ) || event.type === 'click' ) {
     575                event.preventDefault();
     576                $('#' + taxonomy + '-tabs a').removeAttr( 'aria-selected' ).attr( 'tabindex', '-1' );
     577                $(this).attr( 'aria-selected', 'true' ).removeAttr( 'tabindex' );
     578                $(this).parent().addClass('tabs').siblings('li').removeClass('tabs');
     579                $('#' + taxonomy + '-tabs').siblings('.tabs-panel').hide();
     580                $(t).show();
     581                if ( '#' + taxonomy + '-all' == t ) {
     582                    deleteUserSetting( settingName );
     583                } else {
     584                    setUserSetting( settingName, 'pop' );
     585                }
     586            }
     587            if ( event.type === 'keyup' && ( event.key === 'ArrowRight' || event.key === 'ArrowLeft' ) ) {
     588                $(this).attr( 'tabindex', '-1' );
     589                let next = $(this).parent('li').next();
     590                let prev = $(this).parent('li').prev();
     591                if ( next.length > 0 ) {
     592                    next.find('a').removeAttr( 'tabindex');
     593                    next.find('a').trigger( 'focus' );
     594                } else {
     595                    prev.find('a').removeAttr( 'tabindex');
     596                    prev.find('a').trigger( 'focus' );
     597                }
    579598            }
    580599        });
  • trunk/src/wp-admin/includes/meta-boxes.php

    r61651 r61764  
    645645    ?>
    646646    <div id="taxonomy-<?php echo $tax_name; ?>" class="categorydiv">
    647         <ul id="<?php echo $tax_name; ?>-tabs" class="category-tabs">
    648             <li class="tabs"><a href="#<?php echo $tax_name; ?>-all"><?php echo $taxonomy->labels->all_items; ?></a></li>
    649             <li class="hide-if-no-js"><a href="#<?php echo $tax_name; ?>-pop"><?php echo esc_html( $taxonomy->labels->most_used ); ?></a></li>
     647        <ul id="<?php echo $tax_name; ?>-tabs" class="category-tabs">
     648            <li class="tabs"><a href="#<?php echo $tax_name; ?>-all"><?php echo $taxonomy->labels->all_items; ?></a></li>
     649            <li class="hide-if-no-js"><a href="#<?php echo $tax_name; ?>-pop"><?php echo esc_html( $taxonomy->labels->most_used ); ?></a></li>
    650650        </ul>
    651651
    652         <div id="<?php echo $tax_name; ?>-pop" class="tabs-panel" style="display: none;">
     652        <div id="<?php echo $tax_name; ?>-pop" class="tabs-panel" style="display: none;">
    653653            <ul id="<?php echo $tax_name; ?>checklist-pop" class="categorychecklist form-no-clear" >
    654654                <?php $popular_ids = wp_popular_terms_checklist( $tax_name ); ?>
     
    656656        </div>
    657657
    658         <div id="<?php echo $tax_name; ?>-all" class="tabs-panel">
     658        <div id="<?php echo $tax_name; ?>-all" class="tabs-panel">
    659659            <?php
    660660            $name = ( 'category' === $tax_name ) ? 'post_category' : 'tax_input[' . $tax_name . ']';
     
    11771177    ?>
    11781178<div id="taxonomy-linkcategory" class="categorydiv">
    1179     <ul id="category-tabs" class="category-tabs">
    1180         <li class="tabs"><a href="#categories-all"><?php _e( 'All categories' ); ?></a></li>
    1181         <li class="hide-if-no-js"><a href="#categories-pop"><?php _ex( 'Most Used', 'categories' ); ?></a></li>
     1179    <ul id="category-tabs" class="category-tabs">
     1180        <li class="tabs"><a href="#categories-all"><?php _e( 'All categories' ); ?></a></li>
     1181        <li class="hide-if-no-js"><a href="#categories-pop"><?php _ex( 'Most Used', 'categories' ); ?></a></li>
    11821182    </ul>
    11831183
    1184     <div id="categories-all" class="tabs-panel">
     1184    <div id="categories-all" class="tabs-panel">
    11851185        <ul id="categorychecklist" data-wp-lists="list:category" class="categorychecklist form-no-clear">
    11861186            <?php
     
    11941194    </div>
    11951195
    1196     <div id="categories-pop" class="tabs-panel" style="display: none;">
     1196    <div id="categories-pop" class="tabs-panel" style="display: none;">
    11971197        <ul id="categorychecklist-pop" class="categorychecklist form-no-clear">
    11981198            <?php wp_popular_terms_checklist( 'link_category' ); ?>
Note: See TracChangeset for help on using the changeset viewer.