woocommerce/plugins/woocommerce-blocks/assets/js/base/context/hooks/use-store-notices.ts

117 lines
2.8 KiB
TypeScript

/**
* 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,
};
};