From 0dd5a726c044e65c6d031c88672150e6ab9f3c2c Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Thu, 6 Feb 2020 16:25:39 +0200 Subject: [PATCH 1/6] adds errors to the media replace control --- .../components/media-replace-flow/index.js | 34 ++++++++++++++++--- .../components/media-replace-flow/style.scss | 18 ++++++++++ 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/packages/block-editor/src/components/media-replace-flow/index.js b/packages/block-editor/src/components/media-replace-flow/index.js index 79719047690a4..162aad1022604 100644 --- a/packages/block-editor/src/components/media-replace-flow/index.js +++ b/packages/block-editor/src/components/media-replace-flow/index.js @@ -1,7 +1,12 @@ +/** + * External dependencies + */ +import { uniqueId } from 'lodash'; + /** * WordPress dependencies */ -import { useState, createRef } from '@wordpress/element'; +import { useState, createRef, renderToString } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { speak } from '@wordpress/a11y'; import { @@ -11,10 +16,9 @@ import { ToolbarGroup, Button, Dropdown, - withNotices, } from '@wordpress/components'; +import { withDispatch, useSelect } from '@wordpress/data'; import { DOWN } from '@wordpress/keycodes'; -import { useSelect } from '@wordpress/data'; import { compose } from '@wordpress/compose'; import { upload, media as mediaIcon } from '@wordpress/icons'; @@ -32,19 +36,31 @@ const MediaReplaceFlow = ( { accept, onSelect, onSelectURL, - onError, name = __( 'Replace' ), + createNotice, + removeNotice, } ) => { const [ mediaURLValue, setMediaURLValue ] = useState( mediaURL ); const mediaUpload = useSelect( ( select ) => { return select( 'core/block-editor' ).getSettings().mediaUpload; }, [] ); const editMediaButtonRef = createRef(); + const errorNoticeID = uniqueId(); + + const onError = ( message ) => { + createNotice( 'error', renderToString( message ), { + speak: true, + id: errorNoticeID, + isDismissible: true, + __unstableHTML: true, + } ); + }; const selectMedia = ( media ) => { onSelect( media ); setMediaURLValue( media.url ); speak( __( 'The media file has been replaced' ) ); + removeNotice( errorNoticeID ); }; const selectURL = ( newURL ) => { @@ -154,4 +170,12 @@ const MediaReplaceFlow = ( { ); }; -export default compose( withNotices )( MediaReplaceFlow ); +export default compose( [ + withDispatch( ( dispatch ) => { + const { createNotice, removeNotice } = dispatch( 'core/notices' ); + return { + createNotice, + removeNotice, + }; + } ), +] )( MediaReplaceFlow ); diff --git a/packages/block-editor/src/components/media-replace-flow/style.scss b/packages/block-editor/src/components/media-replace-flow/style.scss index c502f5339c9fd..1b620d851f527 100644 --- a/packages/block-editor/src/components/media-replace-flow/style.scss +++ b/packages/block-editor/src/components/media-replace-flow/style.scss @@ -15,6 +15,24 @@ margin-left: 4px; } +.block-editor-media-flow__error { + padding: 0 20px 20px 20px; + max-width: 255px; + + .components-with-notices-ui { + max-width: 255px; + + .components-notice__content { + overflow: hidden; + word-wrap: break-word; + } + .components-notice__dismiss { + position: absolute; + right: 10px; + } + } +} + .block-editor-media-flow__url-input { margin-top: $grid-unit-20; From 09bb7c3cba90ffce5598b1aa0b73d8cd3c165205 Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Thu, 20 Feb 2020 18:17:02 +0200 Subject: [PATCH 2/6] adds a debounced speak message --- .../src/components/media-replace-flow/index.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/block-editor/src/components/media-replace-flow/index.js b/packages/block-editor/src/components/media-replace-flow/index.js index 162aad1022604..29be577946e07 100644 --- a/packages/block-editor/src/components/media-replace-flow/index.js +++ b/packages/block-editor/src/components/media-replace-flow/index.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { uniqueId } from 'lodash'; +import { uniqueId, debounce } from 'lodash'; /** * WordPress dependencies @@ -48,8 +48,13 @@ const MediaReplaceFlow = ( { const errorNoticeID = uniqueId(); const onError = ( message ) => { - createNotice( 'error', renderToString( message ), { - speak: true, + const renderMsg = renderToString( message ); + const speakMsg = debounce( + () => speak( renderToString( message ) ), + 5000 + ); + speakMsg(); + createNotice( 'error', renderMsg, { id: errorNoticeID, isDismissible: true, __unstableHTML: true, From c9edd04c86e9919762c4fa33973ff2c2e80a4925 Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Wed, 11 Mar 2020 13:56:00 +0200 Subject: [PATCH 3/6] removes __unstableHTML dependency, uses built in speak, creates notice with a small delay, VO works --- .../components/media-replace-flow/index.js | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/packages/block-editor/src/components/media-replace-flow/index.js b/packages/block-editor/src/components/media-replace-flow/index.js index 29be577946e07..ea89b68cc465b 100644 --- a/packages/block-editor/src/components/media-replace-flow/index.js +++ b/packages/block-editor/src/components/media-replace-flow/index.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { uniqueId, debounce } from 'lodash'; +import { uniqueId } from 'lodash'; /** * WordPress dependencies @@ -48,17 +48,17 @@ const MediaReplaceFlow = ( { const errorNoticeID = uniqueId(); const onError = ( message ) => { - const renderMsg = renderToString( message ); - const speakMsg = debounce( - () => speak( renderToString( message ) ), - 5000 - ); - speakMsg(); - createNotice( 'error', renderMsg, { - id: errorNoticeID, - isDismissible: true, - __unstableHTML: true, - } ); + const errorElement = document.createElement( 'div' ); + errorElement.innerHTML = renderToString( message ); + const renderMsg = + errorElement.textContent || errorElement.innerText || ''; + setTimeout( () => { + createNotice( 'error', renderMsg, { + speak: true, + id: errorNoticeID, + isDismissible: true, + } ); + }, 1000 ); }; const selectMedia = ( media ) => { @@ -72,11 +72,10 @@ const MediaReplaceFlow = ( { onSelectURL( newURL ); }; - const uploadFiles = ( event, closeDropdown ) => { + const uploadFiles = ( event ) => { const files = event.target.files; const setMedia = ( [ media ] ) => { selectMedia( media ); - closeDropdown(); }; mediaUpload( { allowedTypes, From bfa1008d59a370d8ec5e6989188e5303abf0b62c Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Fri, 13 Mar 2020 09:25:32 +0200 Subject: [PATCH 4/6] adds comments to setTimeout call for notice and HTML removal on notice error, adds prefix to notice uniqueid --- .../src/components/media-replace-flow/index.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/media-replace-flow/index.js b/packages/block-editor/src/components/media-replace-flow/index.js index ea89b68cc465b..1d67625fefbc7 100644 --- a/packages/block-editor/src/components/media-replace-flow/index.js +++ b/packages/block-editor/src/components/media-replace-flow/index.js @@ -45,13 +45,25 @@ const MediaReplaceFlow = ( { return select( 'core/block-editor' ).getSettings().mediaUpload; }, [] ); const editMediaButtonRef = createRef(); - const errorNoticeID = uniqueId(); + const errorNoticeID = uniqueId( + 'block-editor/media-replace-flow/error-notice/' + ); const onError = ( message ) => { const errorElement = document.createElement( 'div' ); errorElement.innerHTML = renderToString( message ); + // The default error contains some HTML that, + // for example, makes the filename bold. + // The notice, by default, accepts strings only and so + // I am removing the html from the error. const renderMsg = errorElement.textContent || errorElement.innerText || ''; + // We need to set a timeout for showing the notice + // so that VoiceOver and possibly other screen readers + // can announce the error afer the toolbar button + // regains focus once the upload dialog closes. + // Otherwise VO simply skips over the notice and announces + // the focused element and the open menu. setTimeout( () => { createNotice( 'error', renderMsg, { speak: true, From 1b7d38eb29718fc402e65d4d320f70b5cd42e431 Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Fri, 13 Mar 2020 09:26:27 +0200 Subject: [PATCH 5/6] updates comment wording --- .../block-editor/src/components/media-replace-flow/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/media-replace-flow/index.js b/packages/block-editor/src/components/media-replace-flow/index.js index 1d67625fefbc7..ed72ad8a5f25f 100644 --- a/packages/block-editor/src/components/media-replace-flow/index.js +++ b/packages/block-editor/src/components/media-replace-flow/index.js @@ -55,7 +55,7 @@ const MediaReplaceFlow = ( { // The default error contains some HTML that, // for example, makes the filename bold. // The notice, by default, accepts strings only and so - // I am removing the html from the error. + // we need to remove the html from the error. const renderMsg = errorElement.textContent || errorElement.innerText || ''; // We need to set a timeout for showing the notice From 12ef4e94c4caca09fb1d9a61f21e2cf4d59572e5 Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Fri, 13 Mar 2020 09:38:10 +0200 Subject: [PATCH 6/6] fixes rebased style for media replace flow --- .../components/media-replace-flow/style.scss | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/packages/block-editor/src/components/media-replace-flow/style.scss b/packages/block-editor/src/components/media-replace-flow/style.scss index 1b620d851f527..bde255a184214 100644 --- a/packages/block-editor/src/components/media-replace-flow/style.scss +++ b/packages/block-editor/src/components/media-replace-flow/style.scss @@ -15,24 +15,6 @@ margin-left: 4px; } -.block-editor-media-flow__error { - padding: 0 20px 20px 20px; - max-width: 255px; - - .components-with-notices-ui { - max-width: 255px; - - .components-notice__content { - overflow: hidden; - word-wrap: break-word; - } - .components-notice__dismiss { - position: absolute; - right: 10px; - } - } -} - .block-editor-media-flow__url-input { margin-top: $grid-unit-20; @@ -68,3 +50,21 @@ } } } + +.block-editor-media-flow__error { + padding: 0 20px 20px 20px; + max-width: 255px; + + .components-with-notices-ui { + max-width: 255px; + + .components-notice__content { + overflow: hidden; + word-wrap: break-word; + } + .components-notice__dismiss { + position: absolute; + right: 10px; + } + } +}