Skip to content

Commit

Permalink
fix(toast): fixing maxVisibleToasts, solid variant promise, promise t…
Browse files Browse the repository at this point in the history
…imer (#4881)

* fix: maxVisibleToasts functionality

* chore: adding the changeset

* fix: starting the toast timer when the promise is resolved

* fix: spinner invisible in solid variants
  • Loading branch information
macci001 authored Feb 21, 2025
1 parent 57b1181 commit 29df4f5
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 22 deletions.
6 changes: 6 additions & 0 deletions .changeset/slow-dogs-travel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@heroui/toast": patch
---

fixing maxVisibleToast functionality in toast (#4870)
For promises, starting the timer only after the promise is resolved
7 changes: 6 additions & 1 deletion packages/components/toast/src/toast-region.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,11 @@ export function ToastRegion<T extends ToastProps>({
return null;
}

if (total - index <= 4 || (isHovered && total - index <= maxVisibleToasts + 1)) {
if (
disableAnimation ||
total - index <= 4 ||
(isHovered && total - index <= maxVisibleToasts + 1)
) {
return (
<Toast
key={toast.key}
Expand All @@ -85,6 +89,7 @@ export function ToastRegion<T extends ToastProps>({
heights={heights}
index={index}
isRegionExpanded={isHovered || isTouched}
maxVisibleToasts={maxVisibleToasts}
placement={placement}
setHeights={setHeights}
toastOffset={toastOffset}
Expand Down
2 changes: 1 addition & 1 deletion packages/components/toast/src/toast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const Toast = forwardRef<"div", ToastProps>((props, ref) => {
<Spinner
aria-label="loadingIcon"
classNames={{wrapper: getLoadingIconProps().className}}
color={color ?? "default"}
color={"current"}
/>
)
: null;
Expand Down
39 changes: 27 additions & 12 deletions packages/components/toast/src/use-toast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ interface Props<T> extends Omit<HTMLHeroUIProps<"div">, "title">, ToastProps {
isRegionExpanded: boolean;
placement?: ToastPlacement;
toastOffset?: number;
maxVisibleToasts: number;
}

export type UseToastProps<T = ToastProps> = Props<T> &
Expand Down Expand Up @@ -158,6 +159,7 @@ export function useToast<T extends ToastProps>(originalProps: UseToastProps<T>)
icon,
onClose,
severity,
maxVisibleToasts,
...otherProps
} = props;

Expand Down Expand Up @@ -193,9 +195,18 @@ export function useToast<T extends ToastProps>(originalProps: UseToastProps<T>)
}
}, []);

const [isLoading, setIsLoading] = useState<boolean>(!!promiseProp);

useEffect(() => {
if (!promiseProp) return;
promiseProp.finally(() => {
setIsLoading(false);
});
}, [promiseProp]);

useEffect(() => {
const updateProgress = (timestamp: number) => {
if (!timeout) {
if (!timeout || isLoading) {
return;
}

Expand Down Expand Up @@ -238,16 +249,16 @@ export function useToast<T extends ToastProps>(originalProps: UseToastProps<T>)
cancelAnimationFrame(animationRef.current);
}
};
}, [timeout, shouldShowTimeoutProgess, state, isToastHovered, index, total, isRegionExpanded]);

const [isLoading, setIsLoading] = useState<boolean>(!!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;
Expand Down Expand Up @@ -486,7 +497,10 @@ export function useToast<T extends ToastProps>(originalProps: UseToastProps<T>)
"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);
Expand Down Expand Up @@ -593,6 +607,7 @@ export function useToast<T extends ToastProps>(originalProps: UseToastProps<T>)
shouldCloseToast,
slots,
toastOffset,
maxVisibleToasts,
],
);

Expand Down
26 changes: 18 additions & 8 deletions packages/components/toast/stories/toast.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ export default {
"top-center",
],
},
maxVisibleToasts: {
control: {type: "number"},
},
hideCloseButton: {
control: {
type: "boolean",
Expand Down Expand Up @@ -80,7 +83,7 @@ const defaultProps = {
const Template = (args: ToastProps) => {
return (
<>
<ToastProvider placement={args.placement} />
<ToastProvider maxVisibleToasts={args.maxVisibleToasts} placement={args.placement} />
<div>
<Button
onPress={() => {
Expand All @@ -100,7 +103,7 @@ const Template = (args: ToastProps) => {
const ShowTimeoutProgressTemplate = (args: ToastProps) => {
return (
<>
<ToastProvider placement={args.placement} />
<ToastProvider maxVisibleToasts={args.maxVisibleToasts} placement={args.placement} />
<Button
onPress={() => {
addToast({
Expand All @@ -121,7 +124,7 @@ const ShowTimeoutProgressTemplate = (args: ToastProps) => {
const WithEndContentTemplate = (args) => {
return (
<>
<ToastProvider placement={args.placement} />
<ToastProvider maxVisibleToasts={args.maxVisibleToasts} placement={args.placement} />
<Button
onPress={() => {
addToast({
Expand All @@ -147,7 +150,7 @@ const WithEndContentTemplate = (args) => {
const PlacementTemplate = (args: ToastProps) => {
return (
<>
<ToastProvider placement={args.placement} />
<ToastProvider maxVisibleToasts={args.maxVisibleToasts} placement={args.placement} />
<div>
<Button
onPress={() => {
Expand All @@ -168,7 +171,11 @@ const PlacementTemplate = (args: ToastProps) => {
const DisableAnimationTemplate = (args: ToastProps) => {
return (
<>
<ToastProvider disableAnimation={true} placement={args.placement} />
<ToastProvider
disableAnimation={true}
maxVisibleToasts={args.maxVisibleToasts}
placement={args.placement}
/>
<div>
<Button
onPress={() => {
Expand All @@ -189,14 +196,16 @@ const DisableAnimationTemplate = (args: ToastProps) => {
const PromiseToastTemplate = (args: ToastProps) => {
return (
<>
<ToastProvider placement={args.placement} />
<ToastProvider maxVisibleToasts={args.maxVisibleToasts} placement={args.placement} />
<div>
<Button
onPress={() => {
addToast({
title: "Toast Title",
description: "Toast Displayed Successfully",
promise: new Promise((resolve) => setTimeout(resolve, 5000)),
promise: new Promise((resolve) => setTimeout(resolve, 3000)),
timeout: 3000,
shouldShowTimeoutProgess: false,
...args,
});
}}
Expand Down Expand Up @@ -265,7 +274,7 @@ const CustomToastTemplate = (args) => {

return (
<>
<ToastProvider placement={args.placement} />
<ToastProvider maxVisibleToasts={args.maxVisibleToasts} placement={args.placement} />
<div className="flex gap-2">
{colors.map((color, idx) => (
<CustomToastComponent key={idx} color={color} />
Expand All @@ -279,6 +288,7 @@ const CustomCloseButtonTemplate = (args) => {
return (
<>
<ToastProvider
maxVisibleToasts={args.maxVisibleToasts}
placement={args.placement}
toastProps={{
classNames: {
Expand Down

0 comments on commit 29df4f5

Please sign in to comment.