Make WordPress Core


Ignore:
Timestamp:
06/21/2023 09:45:52 PM (3 years ago)
Author:
joedolson
Message:

Administration: Set accessible state for list table headers.

Implement aria-sort and change icon states to indicate current sort for list tables. Allow screen reader users to get context about the current sort and allow sighted users to know how the table is currently sorted.

Props afercia, rianrietveld, joedolson, alexstine, johnjamesjacoby.
Fixes #32170.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/class-wp-list-table.php

    r55954 r55971  
    11101110         * The format is:
    11111111         * - `'internal-name' => 'orderby'`
     1112         * - `'internal-name' => array( 'orderby', bool, 'abbr', 'orderby-text', 'initially-sorted-column-order' )` -
    11121113         * - `'internal-name' => array( 'orderby', 'asc' )` - The second element sets the initial sorting order.
    11131114         * - `'internal-name' => array( 'orderby', true )`  - The second element makes the initial order descending.
    11141115         *
    1115          * @since 3.1.0
     1116         * In the second format, passing true as second parameter will make the initial
     1117         * sorting order be descending. Following parameters add a short column name to
     1118         * be used as 'abbr' attribute, a translatable string for the current sorting
     1119         * and the initial order for the initial sorted column, 'asc' or 'desc' (default: false).
     1120         *
     1121         * @since 3.1.0
     1122         * @since 6.3.0 Added 'abbr', 'orderby-text' and 'initially-sorted-column-order'.
    11161123         *
    11171124         * @return array
     
    12541261
    12551262                        $data = (array) $data;
     1263                        // Descending initial sorting.
    12561264                        if ( ! isset( $data[1] ) ) {
    12571265                                $data[1] = false;
     1266                        }
     1267                        // Current sorting translatable string.
     1268                        if ( ! isset( $data[2] ) ) {
     1269                                $data[2] = '';
     1270                        }
     1271                        // Initial view sorted column and asc/desc order, default: false.
     1272                        if ( ! isset( $data[3] ) ) {
     1273                                $data[3] = false;
     1274                        }
     1275                        // Initial order for the initial sorted column, default: false.
     1276                        if ( ! isset( $data[4] ) ) {
     1277                                $data[4] = false;
    12581278                        }
    12591279
     
    12931313                $current_url = remove_query_arg( 'paged', $current_url );
    12941314
     1315                // When users click on a column header to sort by other columns.
    12951316                if ( isset( $_GET['orderby'] ) ) {
    12961317                        $current_orderby = $_GET['orderby'];
     1318                        // In the initial view there's no orderby parameter.
    12971319                } else {
    12981320                        $current_orderby = '';
    12991321                }
    13001322
    1301                 if ( isset( $_GET['order'] ) && 'desc' === $_GET['order'] ) {
     1323                // Not in the initial view and descending order.
     1324                if ( isset( $_GET['order'] ) && 'desc' == $_GET['order'] ) {
    13021325                        $current_order = 'desc';
    13031326                } else {
     1327                        // The initial view is not always 'asc' we'll take care of this below.
    13041328                        $current_order = 'asc';
    13051329                }
     
    13181342
    13191343                foreach ( $columns as $column_key => $column_display_name ) {
    1320                         $class = array( 'manage-column', "column-$column_key" );
     1344                        $class          = array( 'manage-column', "column-$column_key" );
     1345                        $aria_sort_attr = '';
     1346                        $abbr_attr      = '';
     1347                        $order_text     = '';
    13211348
    13221349                        if ( in_array( $column_key, $hidden, true ) ) {
     
    13351362
    13361363                        if ( isset( $sortable[ $column_key ] ) ) {
    1337                                 list( $orderby, $desc_first ) = $sortable[ $column_key ];
    1338 
     1364                                list( $orderby, $desc_first, $abbr, $orderby_text, $initial_order ) = $sortable[ $column_key ];
     1365
     1366                                /*
     1367                                 * We're in the initial view and there's no $_GET['orderby'] then check if the
     1368                                 * initial sorting information is set in the sortable columns and use that.
     1369                                 */
     1370                                if ( '' === $current_orderby && $initial_order ) {
     1371                                        // Use the initially sorted column $orderby as current orderby.
     1372                                        $current_orderby = $orderby;
     1373                                        // Use the initially sorted column asc/desc order as initial order.
     1374                                        $current_order = $initial_order;
     1375                                }
     1376
     1377                                /*
     1378                                 * True in the initial view when an initial orderby is set via get_sortable_columns()
     1379                                 * and true in the sorted views when the actual $_GET['orderby'] is equal to $orderby.
     1380                                 */
    13391381                                if ( $current_orderby === $orderby ) {
    1340                                         $order = 'asc' === $current_order ? 'desc' : 'asc';
    1341 
     1382                                        // The sorted column. The `aria-sort` attribute must be set only on the sorted column.
     1383                                        if ( 'asc' == $current_order ) {
     1384                                                $order          = 'desc';
     1385                                                $aria_sort_attr = ' aria-sort="ascending"';
     1386                                        } else {
     1387                                                $order          = 'asc';
     1388                                                $aria_sort_attr = ' aria-sort="descending"';
     1389                                        }
    13421390                                        $class[] = 'sorted';
    13431391                                        $class[] = $current_order;
    13441392                                } else {
     1393                                        // The other sortable columns.
    13451394                                        $order = strtolower( $desc_first );
    13461395
     
    13491398                                        }
    13501399
    1351                                         $class[] = 'sortable';
    1352                                         $class[] = 'desc' === $order ? 'asc' : 'desc';
     1400                                        $class[]    = 'sortable';
     1401                                        $class[]    = 'desc' === $order ? 'asc' : 'desc';
     1402                                        $order_text = 'asc' === $order ? __( 'Sort ascending.' ) : __( 'Sort descending.' );
    13531403                                }
    1354 
    1355                                 $column_display_name = sprintf(
    1356                                         '<a href="%s"><span>%s</span><span class="sorting-indicator"></span></a>',
    1357                                         esc_url( add_query_arg( compact( 'orderby', 'order' ), $current_url ) ),
    1358                                         $column_display_name
    1359                                 );
     1404                                if ( '' !== $order_text ) {
     1405                                        $order_text = ' <span class="screen-reader-text">' . $order_text . '</span>';
     1406                                }
     1407
     1408                                // Print an 'abbr' attribute if a value is provided via get_sortable_columns().
     1409                                $abbr_attr           = $abbr ? ' abbr="' . esc_attr( $abbr ) . '"' : '';
     1410                                $column_display_name = '<a href="' . esc_url( add_query_arg( compact( 'orderby', 'order' ), $current_url ) ) . '"><span>' . $column_display_name . '</span><span class="sorting-indicators"><span class="sorting-indicator asc" aria-hidden="true"></span><span class="sorting-indicator desc" aria-hidden="true"></span>' . $order_text . '</a>';
    13601411                        }
    13611412
     
    13681419                        }
    13691420
    1370                         echo "<$tag $scope $id $class>$column_display_name</$tag>";
     1421                        echo "<$tag $scope $id $class $aria_sort_attr $abbr_attr>$column_display_name</$tag>";
     1422                }
     1423        }
     1424
     1425        /**
     1426         * Print a table description with information about current sorting and order.
     1427         *
     1428         * For the table initial view, information about initial orderby and order
     1429         * should be provided via get_sortable_columns().
     1430         *
     1431         * @since 4.3.0
     1432         * @access public
     1433         */
     1434        public function print_table_description() {
     1435                list( $columns, $hidden, $sortable ) = $this->get_column_info();
     1436
     1437                if ( empty( $sortable ) ) {
     1438                        return;
     1439                }
     1440
     1441                // When users click on a column header to sort by other columns.
     1442                if ( isset( $_GET['orderby'] ) ) {
     1443                        $current_orderby = $_GET['orderby'];
     1444                        // In the initial view there's no orderby parameter.
     1445                } else {
     1446                        $current_orderby = '';
     1447                }
     1448
     1449                // Not in the initial view and descending order.
     1450                if ( isset( $_GET['order'] ) && 'desc' == $_GET['order'] ) {
     1451                        $current_order = 'desc';
     1452                } else {
     1453                        // The initial view is not always 'asc' we'll take care of this below.
     1454                        $current_order = 'asc';
     1455                }
     1456
     1457                foreach ( array_keys( $columns ) as $column_key ) {
     1458
     1459                        if ( isset( $sortable[ $column_key ] ) ) {
     1460
     1461                                list( $orderby, $desc_first, $abbr, $orderby_text, $initial_order ) = $sortable[ $column_key ];
     1462
     1463                                if ( ! is_string( $orderby_text ) || '' === $orderby_text ) {
     1464                                        return;
     1465                                }
     1466                                /*
     1467                                 * We're in the initial view and there's no $_GET['orderby'] then check if the
     1468                                 * initial sorting information is set in the sortable columns and use that.
     1469                                 */
     1470                                if ( '' === $current_orderby && $initial_order ) {
     1471                                        // Use the initially sorted column $orderby as current orderby.
     1472                                        $current_orderby = $orderby;
     1473                                        // Use the initially sorted column asc/desc order as initial order.
     1474                                        $current_order = $initial_order;
     1475                                }
     1476
     1477                                /*
     1478                                 * True in the initial view when an initial orderby is set via get_sortable_columns()
     1479                                 * and true in the sorted views when the actual $_GET['orderby'] is equal to $orderby.
     1480                                 */
     1481                                if ( $current_orderby == $orderby ) {
     1482                                        $order_text = 'asc' === $current_order ? __( 'Ascending.' ) : __( 'Descending.' );
     1483                                        echo '<caption  class="screen-reader-text">' . $orderby_text . ' ' . $order_text . '</p>';
     1484
     1485                                        return;
     1486                                }
     1487                        }
    13711488                }
    13721489        }
     
    13851502                ?>
    13861503<table class="wp-list-table <?php echo implode( ' ', $this->get_table_classes() ); ?>">
     1504                <?php $this->print_table_description(); ?>
    13871505        <thead>
    13881506        <tr>
Note: See TracChangeset for help on using the changeset viewer.