| @@ -60,8 +60,9 @@ | ||
| 60 | 60 | removeToast(id); |
| 61 | 61 | }, duration); |
| 62 | 62 | } |
| 63 | 63 | }, |
| 64 | + // eslint-disable-next-line react-hooks/exhaustive-deps | |
| 64 | 65 | [], |
| 65 | 66 | ); |
| 66 | 67 | |
| 67 | 68 | const removeToast = useCallback((id: string) => { |
| @@ -84,12 +85,26 @@ | ||
| 84 | 85 | const ToastContainer: React.FC<ToastContainerProps> = ({ |
| 85 | 86 | toasts, |
| 86 | 87 | onRemove, |
| 87 | 88 | }) => { |
| 89 | + // Sit below the WordPress admin bar (and above it in stacking order) so | |
| 90 | + // toasts aren't hidden behind it on the front-end account page. The admin | |
| 91 | + // bar is 46px on small screens (<=782px) and 32px otherwise; +16px gap. | |
| 92 | + const topOffset = React.useMemo(() => { | |
| 93 | + if (typeof document === "undefined") return 16; | |
| 94 | + if (!document.body.classList.contains("admin-bar")) return 16; | |
| 95 | + const small = typeof window !== "undefined" && window.innerWidth <= 782; | |
| 96 | + return (small ? 46 : 32) + 16; | |
| 97 | + }, []); | |
| 98 | + | |
| 88 | 99 | if (toasts.length === 0) return null; |
| 89 | 100 | |
| 90 | 101 | return ( |
| 91 | - <div className="fixed top-4 right-4 z-[9999] flex flex-col gap-2 pointer-events-none"> | |
| 102 | + <div | |
| 103 | + style={{ top: topOffset }} | |
| 104 | + // z-index above the WP admin bar (99999) so it never hides the toast. | |
| 105 | + className="fixed right-4 z-[100000] flex flex-col gap-2 pointer-events-none" | |
| 106 | + > | |
| 92 | 107 | {toasts.map((toast) => ( |
| 93 | 108 | <ToastItem key={toast.id} toast={toast} onRemove={onRemove} /> |
| 94 | 109 | ))} |
| 95 | 110 | </div> |