/** * External dependencies */ import { useMemo, useRef, useEffect } from '@wordpress/element'; /** * Internal dependencies */ import { useStoreNoticesContext } from '../providers/store-notices/context'; type WPNoticeAction = { label: string; url?: string; onClick?: () => void; }; type WPNotice = { id: string; status: 'success' | 'info' | 'error' | 'warning'; content: string; spokenMessage: string; // eslint-disable-next-line @typescript-eslint/naming-convention __unstableHTML: string; isDismissible: boolean; type: 'default' | 'snackbar'; speak: boolean; actions: WPNoticeAction[]; }; type NoticeOptions = { id: string; type: string; isDismissible: boolean; }; type NoticeCreator = ( text: string, noticeProps: NoticeOptions ) => void; export const useStoreNotices = (): { notices: WPNotice[]; hasNoticesOfType: ( type: string ) => boolean; removeNotices: ( status: string | null ) => void; removeNotice: ( id: string, context: string ) => void; addDefaultNotice: NoticeCreator; addErrorNotice: NoticeCreator; addWarningNotice: NoticeCreator; addInfoNotice: NoticeCreator; addSuccessNotice: NoticeCreator; setIsSuppressed: ( isSuppressed: boolean ) => void; } => { const { notices, createNotice, removeNotice, setIsSuppressed, } = useStoreNoticesContext(); // Added to a ref so the surface for notices doesn't change frequently // and thus can be used as dependencies on effects. const currentNotices = useRef( notices ); // Update notices ref whenever they change useEffect( () => { currentNotices.current = notices; }, [ notices ] ); const noticesApi = useMemo( () => ( { hasNoticesOfType: ( type: 'default' | 'snackbar' ): boolean => { return currentNotices.current.some( ( notice ) => notice.type === type ); }, removeNotices: ( status = null ) => { currentNotices.current.forEach( ( notice ) => { if ( status === null || notice.status === status ) { removeNotice( notice.id ); } } ); }, removeNotice, } ), [ removeNotice ] ); const noticeCreators = useMemo( () => ( { addDefaultNotice: ( text: string, noticeProps = {} ) => void createNotice( 'default', text, { ...noticeProps, } ), addErrorNotice: ( text: string, noticeProps = {} ) => void createNotice( 'error', text, { ...noticeProps, } ), addWarningNotice: ( text: string, noticeProps = {} ) => void createNotice( 'warning', text, { ...noticeProps, } ), addInfoNotice: ( text: string, noticeProps = {} ) => void createNotice( 'info', text, { ...noticeProps, } ), addSuccessNotice: ( text: string, noticeProps = {} ) => void createNotice( 'success', text, { ...noticeProps, } ), } ), [ createNotice ] ); return { notices, ...noticesApi, ...noticeCreators, setIsSuppressed, }; };