Skip to content

Commit

Permalink
Remove react-aria-live
Browse files Browse the repository at this point in the history
* inactive package since 5 years
* still requiring React 16.3.x
* moving over to already used WP a11y' speak
* adding a hook and wrapper component for ease of use, as per downside of original PR: #19615
  • Loading branch information
igorschoester committed Apr 28, 2024
1 parent 02d9de1 commit 40daf80
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 53 deletions.
1 change: 0 additions & 1 deletion packages/js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@
"moment-duration-format": "^2.2.2",
"prop-types": "^15.5.10",
"react-animate-height": "^2.0.23",
"react-aria-live": "^2.0.5",
"react-chartjs-2": "^5.2.0",
"react-helmet": "^6.1.0",
"react-hotkeys-hook": "^4.0.5",
Expand Down
23 changes: 11 additions & 12 deletions packages/js/src/settings/components/route-layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { __, sprintf } from "@wordpress/i18n";
import { Title } from "@yoast/ui-library";
import PropTypes from "prop-types";
import { Helmet } from "react-helmet";
import { LiveAnnouncer, LiveMessage } from "react-aria-live";
import { useDocumentTitle } from "../hooks";
import { useDocumentTitle, useSpokenMessage } from "../hooks";

/**
* @param {Object} props The properties.
Expand All @@ -12,21 +11,18 @@ import { useDocumentTitle } from "../hooks";
* @param {JSX.node} [description] The description.
* @returns {JSX.Element} The route layout component.
*/
const RouteLayout = ( {
children,
title,
description,
} ) => {
const RouteLayout = ( { children, title, description } ) => {
const documentTitle = useDocumentTitle( { prefix: `${ title } ‹ ` } );
const ariaLiveTitle = sprintf(

useSpokenMessage( sprintf(
/* translators: 1: Settings' section title, 2: Yoast SEO */
__( "%1$s Settings - %2$s", "wordpress-seo" ),
title,
"Yoast SEO"
);
) );

return (
<LiveAnnouncer>
<LiveMessage message={ ariaLiveTitle } aria-live="polite" />
<>
<Helmet>
<title>{ documentTitle }</title>
</Helmet>
Expand All @@ -37,7 +33,7 @@ const RouteLayout = ( {
</div>
</header>
{ children }
</LiveAnnouncer>
</>
);
};

Expand All @@ -46,5 +42,8 @@ RouteLayout.propTypes = {
title: PropTypes.string.isRequired,
description: PropTypes.node,
};
RouteLayout.defaultProps = {
description: null,
};

export default RouteLayout;
6 changes: 2 additions & 4 deletions packages/js/src/settings/components/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import { Code, Modal, Title, useNavigationContext, useSvgAria, useToggleState }
import classNames from "classnames";
import { debounce, first, groupBy, includes, isEmpty, map, max, reduce, split, trim, values } from "lodash";
import PropTypes from "prop-types";
import { LiveAnnouncer, LiveMessage } from "react-aria-live";
import { useHotkeys } from "react-hotkeys-hook";
import { useNavigate } from "react-router-dom";
import { safeToLocaleLower } from "../helpers";
import { useParsedUserAgent, useSelectSettings } from "../hooks";
import { SpokenMessage } from "./spoken-message";

const POST_TYPE_OR_TAXONOMY_BREADCRUMB_SETTING_REGEXP = new RegExp( /^input-wpseo_titles-(post_types|taxonomy)-(?<name>\S+)-(maintax|ptparent)$/is );

Expand Down Expand Up @@ -233,9 +233,7 @@ const Search = ( { buttonId = "button-search", modalId = "modal-search" } ) => {
aria-label={ __( "Search", "wordpress-seo" ) }
>
<Modal.Panel hasCloseButton={ false }>
<LiveAnnouncer>
{ a11yMessage && <LiveMessage message={ a11yMessage } aria-live="polite" /> }
</LiveAnnouncer>
<SpokenMessage message={ a11yMessage } aria-live="polite" />
<Combobox as="div" className="yst--m-6" onChange={ handleNavigate }>
<div className="yst-relative">
<SearchIcon
Expand Down
29 changes: 29 additions & 0 deletions packages/js/src/settings/components/spoken-message.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import PropTypes from "prop-types";
import { useSpokenMessage } from "../hooks";

/**
* Announces the message with the given politeness, if a valid message is provided.
* Wraps the `useSpokenMessage` hook in a component.
*
* @link https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions
* @see useSpokenMessage in packages/js/src/settings/hooks/use-spoken-message.js
*
* @param {string} message The message to be announced by assistive technologies.
* @param {?string} [ariaLive] The politeness level for aria-live. Can be "off", "assertive" and anything else defaults to "polite".
*
* @returns {JSX.Element} Null.
*/
export const SpokenMessage = ( { message, ariaLive } ) => {
useSpokenMessage( message, ariaLive );

return null;
};

SpokenMessage.propTypes = {
message: PropTypes.string.isRequired,
ariaLive: PropTypes.string,
};
SpokenMessage.defaultProps = {
// eslint-disable-next-line no-undefined
ariaLive: undefined,
};
1 change: 1 addition & 0 deletions packages/js/src/settings/hooks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export { default as useRouterScrollRestore } from "./use-router-scroll-restore";
export { default as useSelectSettings } from "./use-select-settings";
export { default as useDocumentTitle } from "./use-document-title";
export { default as useNewContentTypeNotification } from "./use-new-content-type-notification";
export { useSpokenMessage } from "./use-spoken-message";
3 changes: 2 additions & 1 deletion packages/js/src/settings/hooks/use-document-title.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useMemo } from "@wordpress/element";
import useSelectSettings from "./use-select-settings";

/**
Expand All @@ -9,7 +10,7 @@ import useSelectSettings from "./use-select-settings";
*/
const useDocumentTitle = ( { prefix = "", postfix = "" } = {} ) => {
const documentTitle = useSelectSettings( "selectPreference", [], "documentTitle" );
return prefix + documentTitle + postfix;
return useMemo( () => [ prefix, documentTitle, postfix ].join( "" ), [ prefix, documentTitle, postfix ] );
};

export default useDocumentTitle;
25 changes: 25 additions & 0 deletions packages/js/src/settings/hooks/use-spoken-message.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { speak } from "@wordpress/a11y";
import { renderToString, useEffect, useMemo } from "@wordpress/element";
import { isString } from "lodash";

/**
* Announces the message with the given politeness, if a valid message is provided.
* Taken from the `useSpokenMessage` hook in Gutenberg Snackbar component.
*
* @link https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions
* @link https://github.com/WordPress/gutenberg/tree/trunk/packages/a11y
*
* @param {string} message The message to be announced by assistive technologies.
* @param {?string} [ariaLive] The politeness level for aria-live. Can be "off", "assertive" and anything else defaults to "polite".
*
* @returns {void}
*/
export const useSpokenMessage = ( message, ariaLive ) => {
const spokenMessage = useMemo( () => isString( message ) ? message : renderToString( message ), [ message ] );

useEffect( () => {
if ( spokenMessage ) {
speak( spokenMessage, ariaLive );
}
}, [ spokenMessage, ariaLive ] );
};
22 changes: 0 additions & 22 deletions packages/js/tests/settings/__snapshots__/search.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,6 @@ exports[`Search modal should open 1`] = `
data-headlessui-state="open"
id="headlessui-dialog-panel-:r1:"
>
<div>
<div
aria-live="assertive"
role="log"
style="border: 0px; height: 1px; margin: -1px; overflow: hidden; white-space: nowrap; padding: 0px; width: 1px; position: absolute;"
/>
<div
aria-live="assertive"
role="log"
style="border: 0px; height: 1px; margin: -1px; overflow: hidden; white-space: nowrap; padding: 0px; width: 1px; position: absolute;"
/>
<div
aria-live="polite"
role="log"
style="border: 0px; height: 1px; margin: -1px; overflow: hidden; white-space: nowrap; padding: 0px; width: 1px; position: absolute;"
/>
<div
aria-live="polite"
role="log"
style="border: 0px; height: 1px; margin: -1px; overflow: hidden; white-space: nowrap; padding: 0px; width: 1px; position: absolute;"
/>
</div>
<div
class="yst--m-6"
data-headlessui-state=""
Expand Down
14 changes: 1 addition & 13 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11075,7 +11075,6 @@ __metadata:
raf: "npm:^3.4.1"
react: "npm:^18.2.0"
react-animate-height: "npm:^2.0.23"
react-aria-live: "npm:^2.0.5"
react-chartjs-2: "npm:^5.2.0"
react-dom: "npm:^18.2.0"
react-helmet: "npm:^6.1.0"
Expand Down Expand Up @@ -31719,17 +31718,6 @@ __metadata:
languageName: node
linkType: hard

"react-aria-live@npm:^2.0.5":
version: 2.0.5
resolution: "react-aria-live@npm:2.0.5"
dependencies:
uuid: "npm:^3.2.1"
peerDependencies:
react: ^16.3.x
checksum: 10c0/cdbf71a61282ff38945fb524de6de9f00302fa5f047ed19b7a5ff87b325680b97043b0b07e00f4fa0217db7a46a1c130030876728e11d5440b84d007c7b97168
languageName: node
linkType: hard

"react-autosize-textarea@npm:^7.1.0":
version: 7.1.0
resolution: "react-autosize-textarea@npm:7.1.0"
Expand Down Expand Up @@ -37522,7 +37510,7 @@ __metadata:
languageName: node
linkType: hard

"uuid@npm:^3.0.1, uuid@npm:^3.2.1, uuid@npm:^3.3.2":
"uuid@npm:^3.0.1, uuid@npm:^3.3.2":
version: 3.4.0
resolution: "uuid@npm:3.4.0"
bin:
Expand Down

0 comments on commit 40daf80

Please sign in to comment.