Skip to content

Commit

Permalink
Table of contents block accessibility improvements (#54322)
Browse files Browse the repository at this point in the history
* Accessibility improvements for table of contents block.

* Revert save function changes.

* Remove unneeded support.

* Add screen reader description.

* Try using a callback to announce message.

* Revert blockProps change.

* Disable sub-headings.

* Less code for handling onClick callback.
  • Loading branch information
alexstine authored Sep 27, 2023
1 parent 2283d6b commit 9293a5a
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 3 deletions.
28 changes: 26 additions & 2 deletions packages/block-library/src/table-of-contents/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {
import { useDispatch, useSelect } from '@wordpress/data';
import { renderToString } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { useInstanceId } from '@wordpress/compose';
import { store as noticeStore } from '@wordpress/notices';

/**
* Internal dependencies
Expand Down Expand Up @@ -50,6 +52,24 @@ export default function TableOfContentsEdit( {
useObserveHeadings( clientId );

const blockProps = useBlockProps();
const instanceId = useInstanceId(
TableOfContentsEdit,
'table-of-contents'
);

// If a user clicks to a link prevent redirection and show a warning.
const { createWarningNotice, removeNotice } = useDispatch( noticeStore );
let noticeId;
const showRedirectionPreventedNotice = ( event ) => {
event.preventDefault();
// Remove previous warning if any, to show one at a time per block.
removeNotice( noticeId );
noticeId = `block-library/core/table-of-contents/redirection-prevented/${ instanceId }`;
createWarningNotice( __( 'Links are disabled in the editor.' ), {
id: noticeId,
type: 'snackbar',
} );
};

const canInsertList = useSelect(
( select ) => {
Expand Down Expand Up @@ -137,8 +157,12 @@ export default function TableOfContentsEdit( {
return (
<>
<nav { ...blockProps }>
<ol inert="true">
<TableOfContentsList nestedHeadingList={ headingTree } />
<ol>
<TableOfContentsList
nestedHeadingList={ headingTree }
disableLinkActivation={ true }
onClick={ showRedirectionPreventedNotice }
/>
</ol>
</nav>
{ toolbarControls }
Expand Down
30 changes: 29 additions & 1 deletion packages/block-library/src/table-of-contents/list.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* External dependencies
*/
import type { MouseEvent } from 'react';

/**
* WordPress dependencies
*/
Expand All @@ -12,16 +17,30 @@ const ENTRY_CLASS_NAME = 'wp-block-table-of-contents__entry';

export default function TableOfContentsList( {
nestedHeadingList,
disableLinkActivation,
onClick,
}: {
nestedHeadingList: NestedHeadingData[];
disableLinkActivation?: boolean;
onClick?: ( event: MouseEvent< HTMLAnchorElement > ) => void;
} ): WPElement {
return (
<>
{ nestedHeadingList.map( ( node, index ) => {
const { content, link } = node.heading;

const entry = link ? (
<a className={ ENTRY_CLASS_NAME } href={ link }>
<a
className={ ENTRY_CLASS_NAME }
href={ link }
aria-disabled={ disableLinkActivation || undefined }
onClick={
disableLinkActivation &&
'function' === typeof onClick
? onClick
: undefined
}
>
{ content }
</a>
) : (
Expand All @@ -35,6 +54,15 @@ export default function TableOfContentsList( {
<ol>
<TableOfContentsList
nestedHeadingList={ node.children }
disableLinkActivation={
disableLinkActivation
}
onClick={
disableLinkActivation &&
'function' === typeof onClick
? onClick
: undefined
}
/>
</ol>
) : null }
Expand Down

0 comments on commit 9293a5a

Please sign in to comment.