diff --git a/assets/stylesheets/_z-index.scss b/assets/stylesheets/_z-index.scss
index 733a5c3ed756e..92a044a7b899a 100644
--- a/assets/stylesheets/_z-index.scss
+++ b/assets/stylesheets/_z-index.scss
@@ -76,6 +76,10 @@ $z-layers: (
// .edit-post-header { z-index: 30 }
".components-notice-list": 29,
+
+ // Show snackbars above everything (similar to popovers)
+ ".components-snackbar-list": 100000,
+
// Show modal under the wp-admin menus and the popover
".components-modal__screen-overlay": 100000,
diff --git a/docs/manifest-devhub.json b/docs/manifest-devhub.json
index bfdf2e267fef6..f762d1422c454 100644
--- a/docs/manifest-devhub.json
+++ b/docs/manifest-devhub.json
@@ -911,6 +911,12 @@
"markdown_source": "../packages/components/src/slot-fill/README.md",
"parent": "components"
},
+ {
+ "title": "Snackbar",
+ "slug": "snackbar",
+ "markdown_source": "../packages/components/src/snackbar/README.md",
+ "parent": "components"
+ },
{
"title": "Spinner",
"slug": "spinner",
diff --git a/docs/manifest.json b/docs/manifest.json
index 429fd5bc835ae..6fbe894c39d69 100644
--- a/docs/manifest.json
+++ b/docs/manifest.json
@@ -887,6 +887,12 @@
"markdown_source": "https://raw.githubusercontent.com/WordPress/gutenberg/master/packages/components/src/slot-fill/README.md",
"parent": "components"
},
+ {
+ "title": "Snackbar",
+ "slug": "snackbar",
+ "markdown_source": "https://raw.githubusercontent.com/WordPress/gutenberg/master/packages/components/src/snackbar/README.md",
+ "parent": "components"
+ },
{
"title": "Spinner",
"slug": "spinner",
diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md
index 50165750d8a05..e6c72c7dbb190 100644
--- a/packages/components/CHANGELOG.md
+++ b/packages/components/CHANGELOG.md
@@ -9,6 +9,7 @@
### New Feature
- Added a new `HorizontalRule` component.
+- Added a new `Snackbar` component.
### Bug Fix
diff --git a/packages/components/src/index.js b/packages/components/src/index.js
index ce378c0b09e3a..ab0540fa2f232 100644
--- a/packages/components/src/index.js
+++ b/packages/components/src/index.js
@@ -50,6 +50,8 @@ export { default as ResizableBox } from './resizable-box';
export { default as ResponsiveWrapper } from './responsive-wrapper';
export { default as SandBox } from './sandbox';
export { default as SelectControl } from './select-control';
+export { default as Snackbar } from './snackbar';
+export { default as SnackbarList } from './snackbar/list';
export { default as Spinner } from './spinner';
export { default as ServerSideRender } from './server-side-render';
export { default as TabPanel } from './tab-panel';
diff --git a/packages/components/src/snackbar/README.md b/packages/components/src/snackbar/README.md
new file mode 100644
index 0000000000000..c25956fba04c8
--- /dev/null
+++ b/packages/components/src/snackbar/README.md
@@ -0,0 +1,48 @@
+# Snackbar
+
+Use Snackbars to communicate low priority, non-interruptive messages to the user.
+
+## Table of contents
+
+1. [Design guidelines](#design-guidelines)
+2. [Development guidelines](#development-guidelines)
+3. [Related components](#related-components)
+
+## Design guidelines
+
+A Snackbar displays a succinct message that is cleared out after a small delay. It can also offer the user options, like viewing a published post but these options should also be available elsewhere in the UI.
+
+## Development guidelines
+
+### Usage
+
+To display a plain snackbar, pass the message as a `children` prop:
+
+```jsx
+const MySnackbarNotice = () => (
+
+ Post published successfully.
+
+);
+```
+
+For more complex markup, you can pass any JSX element:
+
+```jsx
+const MySnackbarNotice = () => (
+
+ An error occurred: { errorDetails }
.
+
+);
+```
+
+#### Props
+
+The following props are used to control the display of the component.
+
+* `onRemove`: function called when dismissing the notice.
+* `actions`: (array) an array of action objects. Each member object should contain a `label` and either a `url` link string or `onClick` callback function. A `className` property can be used to add custom classes to the button styles.
+
+## Related components
+
+- To create a prominent message that requires a higher-level of attention, use a Notice.
diff --git a/packages/components/src/snackbar/index.js b/packages/components/src/snackbar/index.js
new file mode 100644
index 0000000000000..c5d5674ff408d
--- /dev/null
+++ b/packages/components/src/snackbar/index.js
@@ -0,0 +1,86 @@
+/**
+ * External dependencies
+ */
+import { noop } from 'lodash';
+import classnames from 'classnames';
+
+/**
+ * WordPress dependencies
+ */
+import { useEffect } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+
+/**
+ * Internal dependencies
+ */
+import { Button } from '../';
+
+const NOTICE_TIMEOUT = 10000;
+
+function Snackbar( {
+ className,
+ children,
+ actions = [],
+ onRemove = noop,
+} ) {
+ useEffect( () => {
+ // This rule doesn't account yet for React Hooks
+ // eslint-disable-next-line @wordpress/react-no-unsafe-timeout
+ const timeoutHandle = setTimeout( () => {
+ onRemove();
+ }, NOTICE_TIMEOUT );
+
+ return () => clearTimeout( timeoutHandle );
+ }, [] );
+
+ const classes = classnames( className, 'components-snackbar' );
+
+ return (
+
+
+ { children }
+ { actions.map(
+ (
+ {
+ className: buttonCustomClasses,
+ label,
+ onClick,
+ url,
+ },
+ index
+ ) => {
+ return (
+
+ );
+ }
+
+ ) }
+
+
+ );
+}
+
+export default Snackbar;
diff --git a/packages/components/src/snackbar/list.js b/packages/components/src/snackbar/list.js
new file mode 100644
index 0000000000000..c7cff210a138a
--- /dev/null
+++ b/packages/components/src/snackbar/list.js
@@ -0,0 +1,42 @@
+/**
+ * External dependencies
+ */
+import classnames from 'classnames';
+import { omit, noop } from 'lodash';
+
+/**
+ * Internal dependencies
+ */
+import Snackbar from './';
+
+/**
+* Renders a list of notices.
+*
+* @param {Object} $0 Props passed to the component.
+* @param {Array} $0.notices Array of notices to render.
+* @param {Function} $0.onRemove Function called when a notice should be removed / dismissed.
+* @param {Object} $0.className Name of the class used by the component.
+* @param {Object} $0.children Array of children to be rendered inside the notice list.
+* @return {Object} The rendered notices list.
+*/
+function SnackbarList( { notices, className, children, onRemove = noop } ) {
+ className = classnames( 'components-snackbar-list', className );
+ const removeNotice = ( id ) => () => onRemove( id );
+
+ return (
+
+ { children }
+ { notices.map( ( notice ) => (
+
+ { notice.content }
+
+ ) ) }
+
+ );
+}
+
+export default SnackbarList;
diff --git a/packages/components/src/snackbar/style.scss b/packages/components/src/snackbar/style.scss
new file mode 100644
index 0000000000000..40e8f75837ae6
--- /dev/null
+++ b/packages/components/src/snackbar/style.scss
@@ -0,0 +1,57 @@
+.components-snackbar {
+ font-family: $default-font;
+ font-size: $default-font-size;
+ background-color: $dark-gray-700;
+ border-radius: $radius-round-rectangle;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
+ color: $white;
+ padding: 16px 24px;
+ width: 100%;
+ max-width: 600px;
+ margin: 8px 0 0;
+
+ @include break-small() {
+ width: fit-content;
+ }
+
+ &:hover {
+ background-color: $dark-gray-900;
+ }
+
+ &:focus {
+ background-color: $dark-gray-900;
+ box-shadow:
+ 0 0 0 1px $white,
+ 0 0 0 3px $blue-medium-focus;
+ }
+}
+
+.components-snackbar__action.components-button {
+ margin-left: 32px;
+ color: $white;
+ height: auto;
+ flex-shrink: 0;
+ line-height: $default-line-height;
+
+ &:not(:disabled):not([aria-disabled="true"]):not(.is-default) {
+ text-decoration: underline;
+
+ &:hover {
+ color: $white;
+ text-decoration: none;
+ }
+ }
+}
+
+.components-snackbar__content {
+ display: flex;
+ align-items: baseline;
+ justify-content: space-between;
+ line-height: $default-line-height;
+}
+
+.components-snackbar-list {
+ position: absolute;
+ z-index: z-index(".components-snackbar-list");
+ width: 100%;
+}
diff --git a/packages/components/src/style.scss b/packages/components/src/style.scss
index 66d20f3427df8..39c566be5ad52 100644
--- a/packages/components/src/style.scss
+++ b/packages/components/src/style.scss
@@ -35,6 +35,7 @@
@import "./sandbox/style.scss";
@import "./scroll-lock/style.scss";
@import "./select-control/style.scss";
+@import "./snackbar/style.scss";
@import "./spinner/style.scss";
@import "./text-control/style.scss";
@import "./textarea-control/style.scss";
diff --git a/packages/e2e-test-utils/src/publish-post-with-pre-publish-checks-disabled.js b/packages/e2e-test-utils/src/publish-post-with-pre-publish-checks-disabled.js
index ab7914e4eb508..e8e2acdd04dbc 100644
--- a/packages/e2e-test-utils/src/publish-post-with-pre-publish-checks-disabled.js
+++ b/packages/e2e-test-utils/src/publish-post-with-pre-publish-checks-disabled.js
@@ -6,5 +6,5 @@
*/
export async function publishPostWithPrePublishChecksDisabled() {
await page.click( '.editor-post-publish-button' );
- return page.waitForSelector( '.components-notice.is-success' );
+ return page.waitForSelector( '.components-snackbar' );
}
diff --git a/packages/e2e-test-utils/src/publish-post.js b/packages/e2e-test-utils/src/publish-post.js
index 106e6c2f9abfb..694f40ec09517 100644
--- a/packages/e2e-test-utils/src/publish-post.js
+++ b/packages/e2e-test-utils/src/publish-post.js
@@ -16,5 +16,5 @@ export async function publishPost() {
await page.click( '.editor-post-publish-button' );
// A success notice should show up
- return page.waitForSelector( '.components-notice.is-success' );
+ return page.waitForSelector( '.components-snackbar' );
}
diff --git a/packages/e2e-tests/specs/reusable-blocks.test.js b/packages/e2e-tests/specs/reusable-blocks.test.js
index 73d7b9117bf43..a8ab98c2dd318 100644
--- a/packages/e2e-tests/specs/reusable-blocks.test.js
+++ b/packages/e2e-tests/specs/reusable-blocks.test.js
@@ -42,7 +42,7 @@ describe( 'Reusable Blocks', () => {
// Wait for creation to finish
await page.waitForXPath(
- '//*[contains(@class, "components-notice") and contains(@class, "is-success")]/*[text()="Block created."]'
+ '//*[contains(@class, "components-snackbar")]/*[text()="Block created."]'
);
// Select all of the text in the title field by triple-clicking on it. We
@@ -84,7 +84,7 @@ describe( 'Reusable Blocks', () => {
// Wait for creation to finish
await page.waitForXPath(
- '//*[contains(@class, "components-notice") and contains(@class, "is-success")]/*[text()="Block created."]'
+ '//*[contains(@class, "components-snackbar")]/*[text()="Block created."]'
);
// Save the reusable block
@@ -184,7 +184,7 @@ describe( 'Reusable Blocks', () => {
// Wait for deletion to finish
await page.waitForXPath(
- '//*[contains(@class, "components-notice") and contains(@class, "is-success")]/*[text()="Block deleted."]'
+ '//*[contains(@class, "components-snackbar")]/*[text()="Block deleted."]'
);
// Check that we have an empty post again
@@ -221,7 +221,7 @@ describe( 'Reusable Blocks', () => {
// Wait for creation to finish
await page.waitForXPath(
- '//*[contains(@class, "components-notice") and contains(@class, "is-success")]/*[text()="Block created."]'
+ '//*[contains(@class, "components-snackbar")]/*[text()="Block created."]'
);
// Select all of the text in the title field by triple-clicking on it. We
diff --git a/packages/edit-post/src/components/layout/index.js b/packages/edit-post/src/components/layout/index.js
index 364208959d1b6..ee2b55bbed5d2 100644
--- a/packages/edit-post/src/components/layout/index.js
+++ b/packages/edit-post/src/components/layout/index.js
@@ -84,8 +84,7 @@ function Layout( {
aria-label={ __( 'Editor content' ) }
tabIndex="-1"
>
-
-
+
diff --git a/packages/edit-post/src/components/layout/style.scss b/packages/edit-post/src/components/layout/style.scss
index dc40e6321ced3..4c6458afe2f05 100644
--- a/packages/edit-post/src/components/layout/style.scss
+++ b/packages/edit-post/src/components/layout/style.scss
@@ -6,34 +6,6 @@
.edit-post-layout {
position: relative;
- .components-notice-list {
- position: sticky;
- top: $header-height;
- right: 0;
- color: $dark-gray-900;
-
- @include break-small {
- top: 0;
- }
-
- // Non-dismissible notices.
- &.is-pinned {
- position: relative;
- left: 0;
- top: 0;
- }
- }
-
- .components-notice {
- margin: 0 0 5px;
- padding: 6px 12px;
- min-height: $panel-header-height;
-
- .components-notice__dismiss {
- margin: 10px 5px;
- }
- }
-
// Beyond the mobile breakpoint, the editor bar is fixed, so make room for it eabove the layout content.
@include break-small {
padding-top: $header-height;
@@ -54,6 +26,16 @@
}
}
+// Adjust the position of the notices
+.edit-post-layout__content .components-editor-notices__snackbar {
+ position: fixed;
+ right: 0;
+ bottom: 20px;
+ padding-left: 16px;
+ padding-right: 16px;
+}
+@include editor-left(".edit-post-layout__content .components-editor-notices__snackbar");
+
.edit-post-layout__content {
display: flex;
flex-direction: column;
diff --git a/packages/editor/src/components/editor-notices/index.js b/packages/editor/src/components/editor-notices/index.js
index f899f4a61e0ff..fdab17a01b523 100644
--- a/packages/editor/src/components/editor-notices/index.js
+++ b/packages/editor/src/components/editor-notices/index.js
@@ -6,7 +6,7 @@ import { filter } from 'lodash';
/**
* WordPress dependencies
*/
-import { NoticeList } from '@wordpress/components';
+import { NoticeList, SnackbarList } from '@wordpress/components';
import { withSelect, withDispatch } from '@wordpress/data';
import { compose } from '@wordpress/compose';
@@ -15,17 +15,38 @@ import { compose } from '@wordpress/compose';
*/
import TemplateValidationNotice from '../template-validation-notice';
-export function EditorNotices( { dismissible, notices, ...props } ) {
- if ( dismissible !== undefined ) {
- notices = filter( notices, { isDismissible: dismissible } );
- }
+export function EditorNotices( { notices, onRemove } ) {
+ const dismissibleNotices = filter( notices, {
+ isDismissible: true,
+ type: 'default',
+ } );
+ const nonDismissibleNotices = filter( notices, {
+ isDismissible: false,
+ type: 'default',
+ } );
+ const snackbarNotices = filter( notices, {
+ type: 'snackbar',
+ } );
return (
-
- { dismissible !== false && (
+ <>
+
+
- ) }
-
+
+
+ >
);
}
diff --git a/packages/editor/src/components/editor-notices/style.scss b/packages/editor/src/components/editor-notices/style.scss
new file mode 100644
index 0000000000000..e3387e1e65331
--- /dev/null
+++ b/packages/editor/src/components/editor-notices/style.scss
@@ -0,0 +1,37 @@
+// Dismissible notices.
+.components-editor-notices__dismissible {
+ position: sticky;
+ top: $header-height;
+ right: 0;
+ color: $dark-gray-900;
+
+ @include break-small {
+ top: 0;
+ }
+}
+
+// Non-dismissible notices.
+.components-editor-notices__pinned {
+ position: relative;
+ left: 0;
+ top: 0;
+ right: 0;
+ color: $dark-gray-900;
+}
+
+.components-editor-notices__dismissible,
+.components-editor-notices__pinned {
+ .components-notice {
+ margin: 0 0 5px;
+ padding: 6px 12px;
+ min-height: $panel-header-height;
+
+ .components-notice__dismiss {
+ margin: 10px 5px;
+ }
+ }
+}
+
+.components-editor-notices__snackbar {
+ width: 100%;
+}
diff --git a/packages/editor/src/components/editor-notices/test/index.js b/packages/editor/src/components/editor-notices/test/index.js
deleted file mode 100644
index 655a990aa174f..0000000000000
--- a/packages/editor/src/components/editor-notices/test/index.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * External dependencies
- */
-import { shallow } from 'enzyme';
-
-/**
- * Internal dependencies
- */
-import { EditorNotices } from '../';
-
-describe( 'EditorNotices', () => {
- const notices = [
- { content: 'Eat your vegetables!', isDismissible: true },
- { content: 'Brush your teeth!', isDismissible: true },
- { content: 'Existence is fleeting!', isDismissible: false },
- ];
-
- it( 'renders all notices', () => {
- const wrapper = shallow( );
- expect( wrapper.prop( 'notices' ) ).toHaveLength( 3 );
- expect( wrapper.children() ).toHaveLength( 1 );
- } );
-
- it( 'renders only dismissible notices', () => {
- const wrapper = shallow( );
- expect( wrapper.prop( 'notices' ) ).toHaveLength( 2 );
- expect( wrapper.children() ).toHaveLength( 1 );
- } );
-
- it( 'renders only non-dismissible notices', () => {
- const wrapper = shallow( );
- expect( wrapper.prop( 'notices' ) ).toHaveLength( 1 );
- expect( wrapper.children() ).toHaveLength( 0 );
- } );
-} );
diff --git a/packages/editor/src/store/actions.js b/packages/editor/src/store/actions.js
index 4c340057c6471..03548de3f93ab 100644
--- a/packages/editor/src/store/actions.js
+++ b/packages/editor/src/store/actions.js
@@ -356,12 +356,12 @@ export function* savePost( options = {} ) {
yield dispatch(
'core/notices',
'removeNotice',
- SAVE_POST_NOTICE_ID,
+ SAVE_POST_NOTICE_ID
);
yield dispatch(
'core/notices',
'removeNotice',
- 'autosave-exists',
+ 'autosave-exists'
);
}
diff --git a/packages/editor/src/store/effects/reusable-blocks.js b/packages/editor/src/store/effects/reusable-blocks.js
index 63bc00169c543..ebd4caee7fbed 100644
--- a/packages/editor/src/store/effects/reusable-blocks.js
+++ b/packages/editor/src/store/effects/reusable-blocks.js
@@ -133,6 +133,7 @@ export const saveReusableBlocks = async ( action, store ) => {
const message = isTemporary ? __( 'Block created.' ) : __( 'Block updated.' );
dataDispatch( 'core/notices' ).createSuccessNotice( message, {
id: REUSABLE_BLOCK_NOTICE_ID,
+ type: 'snackbar',
} );
dataDispatch( 'core/block-editor' ).__unstableSaveReusableBlock( id, updatedReusableBlock.id );
@@ -199,6 +200,7 @@ export const deleteReusableBlocks = async ( action, store ) => {
const message = __( 'Block deleted.' );
dataDispatch( 'core/notices' ).createSuccessNotice( message, {
id: REUSABLE_BLOCK_NOTICE_ID,
+ type: 'snackbar',
} );
} catch ( error ) {
dispatch( {
diff --git a/packages/editor/src/store/test/actions.js b/packages/editor/src/store/test/actions.js
index f0ec7c84dab15..ab698ea82a731 100644
--- a/packages/editor/src/store/test/actions.js
+++ b/packages/editor/src/store/test/actions.js
@@ -409,7 +409,7 @@ describe( 'Post generator actions', () => {
'createSuccessNotice',
...[
savedPostMessage,
- { actions: [], id: 'SAVE_POST_NOTICE_ID' },
+ { actions: [], id: 'SAVE_POST_NOTICE_ID', type: 'snackbar' },
]
);
expect( value ).toEqual( expected );
diff --git a/packages/editor/src/store/utils/notice-builder.js b/packages/editor/src/store/utils/notice-builder.js
index 4ef98c74e3a54..9732cff6fa7cf 100644
--- a/packages/editor/src/store/utils/notice-builder.js
+++ b/packages/editor/src/store/utils/notice-builder.js
@@ -67,10 +67,12 @@ export function getNotificationArgumentsForSaveSuccess( data ) {
noticeMessage,
{
id: SAVE_POST_NOTICE_ID,
+ type: 'snackbar',
actions,
},
];
}
+
return [];
}
@@ -103,7 +105,9 @@ export function getNotificationArgumentsForSaveFail( data ) {
messages[ edits.status ] :
__( 'Updating failed' );
- return [ noticeMessage, { id: SAVE_POST_NOTICE_ID } ];
+ return [ noticeMessage, {
+ id: SAVE_POST_NOTICE_ID,
+ } ];
}
/**
@@ -118,6 +122,8 @@ export function getNotificationArgumentsForTrashFail( data ) {
data.error.message && data.error.code !== 'unknown_error' ?
data.error.message :
__( 'Trashing failed' ),
- { id: TRASH_POST_NOTICE_ID },
+ {
+ id: TRASH_POST_NOTICE_ID,
+ },
];
}
diff --git a/packages/editor/src/store/utils/test/notice-builder.js b/packages/editor/src/store/utils/test/notice-builder.js
index a78d03f81fad7..e67215113c1f1 100644
--- a/packages/editor/src/store/utils/test/notice-builder.js
+++ b/packages/editor/src/store/utils/test/notice-builder.js
@@ -28,7 +28,7 @@ describe( 'getNotificationArgumentsForSaveSuccess()', () => {
link: 'some_link',
};
const post = { ...previousPost };
- const defaultExpectedAction = { id: SAVE_POST_NOTICE_ID, actions: [] };
+ const defaultExpectedAction = { id: SAVE_POST_NOTICE_ID, actions: [], type: 'snackbar' };
[
[
'when previous post is not published and post will not be published',
diff --git a/packages/editor/src/style.scss b/packages/editor/src/style.scss
index 63f0e18c9974d..949f751bd72af 100644
--- a/packages/editor/src/style.scss
+++ b/packages/editor/src/style.scss
@@ -1,5 +1,6 @@
@import "./components/autocompleters/style.scss";
@import "./components/document-outline/style.scss";
+@import "./components/editor-notices/style.scss";
@import "./components/error-boundary/style.scss";
@import "./components/page-attributes/style.scss";
@import "./components/post-excerpt/style.scss";
diff --git a/packages/notices/CHANGELOG.md b/packages/notices/CHANGELOG.md
index 3ceb48ea97a3f..7a6fde4663c90 100644
--- a/packages/notices/CHANGELOG.md
+++ b/packages/notices/CHANGELOG.md
@@ -1,3 +1,9 @@
+## Master
+
+### New Features
+
+- Support a new `snackbar` notice type in the `createNotice` action.
+
## 1.1.2 (2019-01-03)
## 1.1.1 (2018-12-12)
diff --git a/packages/notices/src/store/actions.js b/packages/notices/src/store/actions.js
index af74f5b6116fe..5ea46e30a4d65 100644
--- a/packages/notices/src/store/actions.js
+++ b/packages/notices/src/store/actions.js
@@ -38,6 +38,7 @@ export function* createNotice( status = DEFAULT_STATUS, content, options = {} )
context = DEFAULT_CONTEXT,
id = uniqueId( context ),
actions = [],
+ type = 'default',
__unstableHTML,
} = options;
@@ -47,7 +48,11 @@ export function* createNotice( status = DEFAULT_STATUS, content, options = {} )
content = String( content );
if ( speak ) {
- yield { type: 'SPEAK', message: content };
+ yield {
+ type: 'SPEAK',
+ message: content,
+ ariaLive: type === 'snackbar' ? 'polite' : 'assertive',
+ };
}
yield {
@@ -60,6 +65,7 @@ export function* createNotice( status = DEFAULT_STATUS, content, options = {} )
__unstableHTML,
isDismissible,
actions,
+ type,
},
};
}
diff --git a/packages/notices/src/store/controls.js b/packages/notices/src/store/controls.js
index c23e1cbd17168..80c20900dd5f3 100644
--- a/packages/notices/src/store/controls.js
+++ b/packages/notices/src/store/controls.js
@@ -5,6 +5,6 @@ import { speak } from '@wordpress/a11y';
export default {
SPEAK( action ) {
- speak( action.message, 'assertive' );
+ speak( action.message, action.ariaLive || 'assertive' );
},
};
diff --git a/packages/notices/src/store/test/actions.js b/packages/notices/src/store/test/actions.js
index ac6bc522f273a..082949031cbd9 100644
--- a/packages/notices/src/store/test/actions.js
+++ b/packages/notices/src/store/test/actions.js
@@ -34,6 +34,7 @@ describe( 'actions', () => {
isDismissible: true,
id: expect.any( String ),
actions: [],
+ type: 'default',
},
} );
} );
@@ -55,6 +56,7 @@ describe( 'actions', () => {
isDismissible: true,
id: expect.any( String ),
actions: [],
+ type: 'default',
},
} );
} );
@@ -83,6 +85,7 @@ describe( 'actions', () => {
content,
isDismissible: false,
actions: [],
+ type: 'default',
},
} );
} );
@@ -109,6 +112,7 @@ describe( 'actions', () => {
__unstableHTML: true,
isDismissible: false,
actions: [],
+ type: 'default',
},
} );
} );
@@ -133,6 +137,7 @@ describe( 'actions', () => {
content,
isDismissible: true,
id: expect.any( String ),
+ type: 'default',
},
} );
} );
@@ -157,6 +162,7 @@ describe( 'actions', () => {
content,
isDismissible: true,
id: expect.any( String ),
+ type: 'default',
},
} );
} );
@@ -181,6 +187,7 @@ describe( 'actions', () => {
content,
isDismissible: true,
id: expect.any( String ),
+ type: 'default',
},
} );
} );
@@ -205,6 +212,7 @@ describe( 'actions', () => {
content,
isDismissible: true,
id: expect.any( String ),
+ type: 'default',
},
} );
} );
diff --git a/packages/notices/src/store/test/reducer.js b/packages/notices/src/store/test/reducer.js
index 04318796773ec..77869efe8d51b 100644
--- a/packages/notices/src/store/test/reducer.js
+++ b/packages/notices/src/store/test/reducer.js
@@ -36,6 +36,7 @@ describe( 'reducer', () => {
status: 'error',
isDismissible: true,
actions: [],
+ type: 'default',
},
],
} );
@@ -53,6 +54,7 @@ describe( 'reducer', () => {
status: 'error',
isDismissible: true,
actions: [],
+ type: 'default',
},
],
} );
@@ -73,6 +75,7 @@ describe( 'reducer', () => {
status: 'error',
isDismissible: true,
actions: [],
+ type: 'default',
},
{
id: expect.any( String ),
@@ -80,6 +83,7 @@ describe( 'reducer', () => {
status: 'success',
isDismissible: true,
actions: [],
+ type: 'default',
},
],
} );
@@ -134,6 +138,7 @@ describe( 'reducer', () => {
status: 'error',
isDismissible: true,
actions: [],
+ type: 'default',
},
],
} );