Back

90.9% Statements 10/11
87.5% Branches 7/8
75% Functions 3/4
90.9% Lines 10/11

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64      37x                 37x               37x 120x   120x       120x     4x               4x 4x                   120x                            
import { createContext, useCallback, useState } from 'react';
import { NoticeContextType, Notice, NoticeOptions } from './types';
 
const defaultNotice: Notice = {
	message: '',
	title: null,
	options: {
		level: 'info',
		priority: 0,
	},
};
 
export const NoticeContext = createContext< NoticeContextType >( {
	currentNotice: defaultNotice,
	setNotice: null,
	resetNotice: null,
} );
 
// Maybe todo: Add a clearNotice type function to remove any active notices
// No use case yet, but it might be useful in the future
const NoticeContextProvider = ( { children } ) => {
	const [ currentNotice, setCurrentNotice ] = useState< Notice >( defaultNotice );
 
	const resetNotice = useCallback( () => {
		setCurrentNotice( defaultNotice );
	}, [] );
 
	const setNotice = useCallback(
		// If onClose is not provided in the "notice", and close button is not hidden, use the custom onClose function
		( notice: Notice, onClose?: NoticeOptions[ 'onClose' ] ) => {
			const newOptions = {
				...notice.options,
				onClose:
					notice.options?.onClose || ( ! notice.options?.hideCloseButton ? onClose : undefined ),
			};
 
			// Replace the notice only if none is showing or the new one has a higher priority. Read the
			// queued state, since watchers call this several times in one effect pass.
			setCurrentNotice( prev =>
				! prev.message || notice.options.priority > prev.options.priority
					? { ...notice, options: newOptions }
					: prev
			);
		},
		// Changing identity on each notice change re-runs the watchers, e.g. to show the next notice after a close.
		// eslint-disable-next-line react-hooks/exhaustive-deps
		[ currentNotice.message, currentNotice.options.priority ]
	);
 
	return (
		<NoticeContext.Provider
			value={ {
				currentNotice,
				setNotice,
				resetNotice,
			} }
		>
			{ children }
		</NoticeContext.Provider>
	);
};
 
export default NoticeContextProvider;