diff --git a/.changeset/slow-dogs-travel.md b/.changeset/slow-dogs-travel.md new file mode 100644 index 0000000000..3e8f436589 --- /dev/null +++ b/.changeset/slow-dogs-travel.md @@ -0,0 +1,6 @@ +--- +"@heroui/toast": patch +--- + +fixing maxVisibleToast functionality in toast (#4870) +For promises, starting the timer only after the promise is resolved diff --git a/packages/components/toast/src/toast-region.tsx b/packages/components/toast/src/toast-region.tsx index 41a212ece7..54c568661a 100644 --- a/packages/components/toast/src/toast-region.tsx +++ b/packages/components/toast/src/toast-region.tsx @@ -74,7 +74,11 @@ export function ToastRegion({ return null; } - if (total - index <= 4 || (isHovered && total - index <= maxVisibleToasts + 1)) { + if ( + disableAnimation || + total - index <= 4 || + (isHovered && total - index <= maxVisibleToasts + 1) + ) { return ( ({ heights={heights} index={index} isRegionExpanded={isHovered || isTouched} + maxVisibleToasts={maxVisibleToasts} placement={placement} setHeights={setHeights} toastOffset={toastOffset} diff --git a/packages/components/toast/src/toast.tsx b/packages/components/toast/src/toast.tsx index 3ce829f454..372f24b6e2 100644 --- a/packages/components/toast/src/toast.tsx +++ b/packages/components/toast/src/toast.tsx @@ -69,7 +69,7 @@ const Toast = forwardRef<"div", ToastProps>((props, ref) => { ) : null; diff --git a/packages/components/toast/src/use-toast.ts b/packages/components/toast/src/use-toast.ts index a442678767..d52e309001 100644 --- a/packages/components/toast/src/use-toast.ts +++ b/packages/components/toast/src/use-toast.ts @@ -119,6 +119,7 @@ interface Props extends Omit, "title">, ToastProps { isRegionExpanded: boolean; placement?: ToastPlacement; toastOffset?: number; + maxVisibleToasts: number; } export type UseToastProps = Props & @@ -158,6 +159,7 @@ export function useToast(originalProps: UseToastProps) icon, onClose, severity, + maxVisibleToasts, ...otherProps } = props; @@ -193,9 +195,18 @@ export function useToast(originalProps: UseToastProps) } }, []); + const [isLoading, setIsLoading] = useState(!!promiseProp); + + useEffect(() => { + if (!promiseProp) return; + promiseProp.finally(() => { + setIsLoading(false); + }); + }, [promiseProp]); + useEffect(() => { const updateProgress = (timestamp: number) => { - if (!timeout) { + if (!timeout || isLoading) { return; } @@ -238,16 +249,16 @@ export function useToast(originalProps: UseToastProps) cancelAnimationFrame(animationRef.current); } }; - }, [timeout, shouldShowTimeoutProgess, state, isToastHovered, index, total, isRegionExpanded]); - - const [isLoading, setIsLoading] = useState(!!promiseProp); - - useEffect(() => { - if (!promiseProp) return; - promiseProp.finally(() => { - setIsLoading(false); - }); - }, [promiseProp]); + }, [ + timeout, + shouldShowTimeoutProgess, + state, + isToastHovered, + index, + total, + isRegionExpanded, + isLoading, + ]); const Component = as || "div"; const loadingIcon: ReactNode = icon; @@ -486,7 +497,10 @@ export function useToast(originalProps: UseToastProps) "data-drag-value": number; className: string; } => { - const isCloseToEnd = total - index - 1 <= 2; + const comparingValue = isRegionExpanded + ? maxVisibleToasts - 1 + : Math.min(2, maxVisibleToasts - 1); + const isCloseToEnd = total - index - 1 <= comparingValue; const dragDirection = placement === "bottom-center" || placement === "top-center" ? "y" : "x"; const dragConstraints = {left: 0, right: 0, top: 0, bottom: 0}; const dragElastic = getDragElasticConstraints(placement); @@ -593,6 +607,7 @@ export function useToast(originalProps: UseToastProps) shouldCloseToast, slots, toastOffset, + maxVisibleToasts, ], ); diff --git a/packages/components/toast/stories/toast.stories.tsx b/packages/components/toast/stories/toast.stories.tsx index b501f18789..1f6cca2c54 100644 --- a/packages/components/toast/stories/toast.stories.tsx +++ b/packages/components/toast/stories/toast.stories.tsx @@ -49,6 +49,9 @@ export default { "top-center", ], }, + maxVisibleToasts: { + control: {type: "number"}, + }, hideCloseButton: { control: { type: "boolean", @@ -80,7 +83,7 @@ const defaultProps = { const Template = (args: ToastProps) => { return ( <> - +