forked from jordanlambrecht/tracker-tracker
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuseSetToggle.ts
More file actions
39 lines (31 loc) · 864 Bytes
/
useSetToggle.ts
File metadata and controls
39 lines (31 loc) · 864 Bytes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// src/hooks/useSetToggle.ts
"use client"
import { useCallback, useState } from "react"
interface UseSetToggleReturn<T> {
set: Set<T>
toggle: (value: T) => void
has: (value: T) => boolean
reset: (values: Iterable<T>) => void
size: number
}
function useSetToggle<T>(initial: Iterable<T>): UseSetToggleReturn<T> {
const [set, setSet] = useState(() => new Set(initial))
const toggle = useCallback((value: T) => {
setSet((prev) => {
const next = new Set(prev)
if (next.has(value)) next.delete(value)
else next.add(value)
return next
})
}, [])
const reset = useCallback((values: Iterable<T>) => setSet(new Set(values)), [])
return {
set,
toggle,
has: useCallback((value: T) => set.has(value), [set]),
reset,
size: set.size,
}
}
export type { UseSetToggleReturn }
export { useSetToggle }