diff --git a/src/types/index.ts b/src/types/index.ts index 6b353e15..019aa701 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -19,6 +19,18 @@ export type ToastOptions = { * Default value: `success` */ type?: ToastType; + /** + * Use it when need to force hide current toaster and show next with animation. + * Use for overshow toast + * Default value: '250' ms + */ + showNextToastAfter?: number; + /** + * Use it when need to force hide current toaster and show next with animation. + * When `true`, the visible Toast force hides and shows a next after showNextToastAfter ms Toast with next props. + * Default value: 'false' + */ + forceOverride?: boolean; /** * Toast position. * Default value: `top` diff --git a/src/useToast.ts b/src/useToast.ts index ae494db0..8016955e 100644 --- a/src/useToast.ts +++ b/src/useToast.ts @@ -13,6 +13,8 @@ export const DEFAULT_DATA: ToastData = { export const DEFAULT_OPTIONS: Required = { type: 'success', + showNextToastAfter: 250, + forceOverride: false, position: 'top', autoHide: true, visibilityTime: 4000, @@ -59,49 +61,77 @@ export function useToast({ defaultOptions }: UseToastParams) { options.onHide(); }, [clearTimer, log, options]); - const show = React.useCallback( - (params: ToastShowParams) => { - log(`Showing with params: ${JSON.stringify(params)}`); + const showNextToaster = React.useCallback((params: ToastShowParams) => { const { - text1 = DEFAULT_DATA.text1, - text2 = DEFAULT_DATA.text2, - type = initialOptions.type, - position = initialOptions.position, - autoHide = initialOptions.autoHide, - visibilityTime = initialOptions.visibilityTime, - topOffset = initialOptions.topOffset, - bottomOffset = initialOptions.bottomOffset, - keyboardOffset = initialOptions.keyboardOffset, - onShow = initialOptions.onShow, - onHide = initialOptions.onHide, - onPress = initialOptions.onPress, - props = initialOptions.props + text1 = DEFAULT_DATA.text1, + text2 = DEFAULT_DATA.text2, + type = initialOptions.type, + position = initialOptions.position, + autoHide = initialOptions.autoHide, + visibilityTime = initialOptions.visibilityTime, + topOffset = initialOptions.topOffset, + bottomOffset = initialOptions.bottomOffset, + keyboardOffset = initialOptions.keyboardOffset, + onShow = initialOptions.onShow, + onHide = initialOptions.onHide, + onPress = initialOptions.onPress, + props = initialOptions.props } = params; + setData({ - text1, - text2 + text1, + text2 }); setOptions( - mergeIfDefined(initialOptions, { - type, - position, - autoHide, - visibilityTime, - topOffset, - bottomOffset, - keyboardOffset, - onShow, - onHide, - onPress, - props - }) as Required + mergeIfDefined(initialOptions, { + type, + position, + autoHide, + visibilityTime, + topOffset, + bottomOffset, + keyboardOffset, + onShow, + onHide, + onPress, + props + }) as Required ); + + }, [initialOptions]) + + const show = React.useCallback( + (params: ToastShowParams) => { + log(`Showing with params: ${JSON.stringify(params)}`); + const { + forceOverride = initialOptions.forceOverride, + showNextToastAfter = initialOptions.showNextToastAfter, + onShow = initialOptions.onShow, + } = params; + // TODO: validate input // TODO: use a queue when Toast is already visible - setIsVisible(true); - onShow(); + + if (forceOverride) { + if (isVisible) { + hide(); + setTimeout(() => { + showNextToaster(params); + setIsVisible(true); + onShow(); + }, showNextToastAfter) + } else { + showNextToaster(params); + setIsVisible(true); + onShow(); + } + } else { + showNextToaster(params); + setIsVisible(true); + onShow(); + } }, - [initialOptions, log] + [hide, initialOptions.forceOverride, initialOptions.onShow, initialOptions.showNextToastAfter, isVisible, log, showNextToaster] ); React.useEffect(() => {