@sanity/ui 4.0.0-static.40 → 4.0.0-static.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +17 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/core/components/toast/ToastProvider.tsx +17 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type {ResponsiveProp} from '@sanity/ui/css'
|
|
2
2
|
import {AnimatePresence} from 'framer-motion'
|
|
3
|
-
import {startTransition, useMemo, useState} from 'react'
|
|
3
|
+
import {startTransition, useMemo, useRef, useState} from 'react'
|
|
4
4
|
|
|
5
5
|
import {useMounted} from '../../hooks/useMounted'
|
|
6
6
|
import {LayerProvider} from '../../primitives/layer/LayerProvider'
|
|
@@ -28,11 +28,20 @@ export function ToastProvider(props: ToastProviderProps): React.JSX.Element {
|
|
|
28
28
|
const [state, setState] = useState<ToastState>([])
|
|
29
29
|
const mounted = useMounted()
|
|
30
30
|
|
|
31
|
+
const timeoutIdsRef = useRef<Record<string, NodeJS.Timeout | undefined>>({})
|
|
32
|
+
|
|
31
33
|
const value: ToastContextValue = useMemo(() => {
|
|
32
34
|
const push = (params: ToastParams) => {
|
|
33
35
|
const id = params.id ?? generateToastId()
|
|
34
36
|
const duration = params.duration ?? 5000
|
|
35
37
|
|
|
38
|
+
// If the `id` is reused, clear the previous timeout
|
|
39
|
+
const existingTimeoutId = timeoutIdsRef.current[id]
|
|
40
|
+
if (existingTimeoutId) {
|
|
41
|
+
clearTimeout(existingTimeoutId)
|
|
42
|
+
timeoutIdsRef.current[id] = undefined
|
|
43
|
+
}
|
|
44
|
+
|
|
36
45
|
startTransition(() => {
|
|
37
46
|
setState((prevState): ToastState => {
|
|
38
47
|
/**
|
|
@@ -50,18 +59,24 @@ export function ToastProvider(props: ToastProviderProps): React.JSX.Element {
|
|
|
50
59
|
* This function will be passed to the Toast component
|
|
51
60
|
* and called either on close button click or after duration.
|
|
52
61
|
*/
|
|
53
|
-
|
|
62
|
+
function dismiss() {
|
|
54
63
|
startTransition(() => {
|
|
55
64
|
if (timeoutId) {
|
|
56
65
|
clearTimeout(timeoutId)
|
|
57
66
|
}
|
|
58
67
|
|
|
59
68
|
setState((currentState) => currentState.filter((toast) => toast.id !== id))
|
|
69
|
+
|
|
70
|
+
// Clear the timeout id from the ref to prevent memory leaks
|
|
71
|
+
timeoutIdsRef.current[id] = undefined
|
|
60
72
|
})
|
|
61
73
|
}
|
|
62
74
|
|
|
63
75
|
const timeoutId = duration === Infinity ? undefined : setTimeout(dismiss, duration)
|
|
64
76
|
|
|
77
|
+
// Set the timeout id in the ref
|
|
78
|
+
timeoutIdsRef.current[id] = timeoutId
|
|
79
|
+
|
|
65
80
|
/**
|
|
66
81
|
* Create updated state by:
|
|
67
82
|
* 1. Removing any existing toast with the same ID (prevents duplicates)
|